From Martin Regner: fix dissection of non-standard parameters.
[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.369 2003/08/28 22:51:07 guy Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  *
12  * Copied from packet-pop.c
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <stdio.h>
34
35 #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 "alignment.h"
44 #include <epan/strutil.h>
45 #include "prefs.h"
46 #include "reassemble.h"
47 #include "tap.h"
48 #include "packet-ipx.h"
49
50 #include "packet-smb-common.h"
51 #include "packet-smb-mailslot.h"
52 #include "packet-smb-pipe.h"
53 #include "packet-dcerpc.h"
54 #include "packet-smb-sidsnooping.h"
55
56 /*
57  * Various specifications and documents about SMB can be found in
58  *
59  *      ftp://ftp.microsoft.com/developr/drg/CIFS/
60  *
61  * and a CIFS specification from the Storage Networking Industry Association
62  * can be found on a link from the page at
63  *
64  *      http://www.snia.org/tech_activities/CIFS
65  *
66  * (it supercedes the document at
67  *
68  *      ftp://ftp.microsoft.com/developr/drg/CIFS/draft-leach-cifs-v1-spec-01.txt
69  *
70  * ).
71  *
72  * There are also some Open Group publications documenting CIFS available
73  * for download; catalog entries for them are at:
74  *
75  *      http://www.opengroup.org/products/publications/catalog/c209.htm
76  *
77  *      http://www.opengroup.org/products/publications/catalog/c195.htm
78  *
79  * The document "NT LAN Manager SMB File Sharing Protocol Extensions"
80  * can be found at
81  *
82  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
83  *
84  * (or, presumably a similar path under the Samba mirrors).  As the
85  * ".doc" indicates, it's a Word document.  Some of the specs from the
86  * Microsoft FTP site can be found in the
87  *
88  *      http://www.samba.org/samba/ftp/specs/
89  *
90  * directory as well.
91  *
92  * Beware - these specs may have errors.
93  */
94 static int proto_smb = -1;
95 static int hf_smb_cmd = -1;
96 static int hf_smb_key = -1;
97 static int hf_smb_session_id = -1;
98 static int hf_smb_sequence_num = -1;
99 static int hf_smb_group_id = -1;
100 static int hf_smb_pid = -1;
101 static int hf_smb_tid = -1;
102 static int hf_smb_uid = -1;
103 static int hf_smb_mid = -1;
104 static int hf_smb_pid_high = -1;
105 static int hf_smb_sig = -1;
106 static int hf_smb_response_to = -1;
107 static int hf_smb_time = -1;
108 static int hf_smb_response_in = -1;
109 static int hf_smb_continuation_to = -1;
110 static int hf_smb_nt_status = -1;
111 static int hf_smb_error_class = -1;
112 static int hf_smb_error_code = -1;
113 static int hf_smb_reserved = -1;
114 static int hf_smb_flags_lock = -1;
115 static int hf_smb_flags_receive_buffer = -1;
116 static int hf_smb_flags_caseless = -1;
117 static int hf_smb_flags_canon = -1;
118 static int hf_smb_flags_oplock = -1;
119 static int hf_smb_flags_notify = -1;
120 static int hf_smb_flags_response = -1;
121 static int hf_smb_flags2_long_names_allowed = -1;
122 static int hf_smb_flags2_ea = -1;
123 static int hf_smb_flags2_sec_sig = -1;
124 static int hf_smb_flags2_long_names_used = -1;
125 static int hf_smb_flags2_esn = -1;
126 static int hf_smb_flags2_dfs = -1;
127 static int hf_smb_flags2_roe = -1;
128 static int hf_smb_flags2_nt_error = -1;
129 static int hf_smb_flags2_string = -1;
130 static int hf_smb_word_count = -1;
131 static int hf_smb_byte_count = -1;
132 static int hf_smb_buffer_format = -1;
133 static int hf_smb_dialect_name = -1;
134 static int hf_smb_dialect_index = -1;
135 static int hf_smb_max_trans_buf_size = -1;
136 static int hf_smb_max_mpx_count = -1;
137 static int hf_smb_max_vcs_num = -1;
138 static int hf_smb_session_key = -1;
139 static int hf_smb_server_timezone = -1;
140 static int hf_smb_encryption_key_length = -1;
141 static int hf_smb_encryption_key = -1;
142 static int hf_smb_primary_domain = -1;
143 static int hf_smb_server = -1;
144 static int hf_smb_max_raw_buf_size = -1;
145 static int hf_smb_server_guid = -1;
146 static int hf_smb_security_blob_len = -1;
147 static int hf_smb_security_blob = -1;
148 static int hf_smb_sm_mode16 = -1;
149 static int hf_smb_sm_password16 = -1;
150 static int hf_smb_sm_mode = -1;
151 static int hf_smb_sm_password = -1;
152 static int hf_smb_sm_signatures = -1;
153 static int hf_smb_sm_sig_required = -1;
154 static int hf_smb_rm_read = -1;
155 static int hf_smb_rm_write = -1;
156 static int hf_smb_server_date_time = -1;
157 static int hf_smb_server_smb_date = -1;
158 static int hf_smb_server_smb_time = -1;
159 static int hf_smb_server_cap_raw_mode = -1;
160 static int hf_smb_server_cap_mpx_mode = -1;
161 static int hf_smb_server_cap_unicode = -1;
162 static int hf_smb_server_cap_large_files = -1;
163 static int hf_smb_server_cap_nt_smbs = -1;
164 static int hf_smb_server_cap_rpc_remote_apis = -1;
165 static int hf_smb_server_cap_nt_status = -1;
166 static int hf_smb_server_cap_level_ii_oplocks = -1;
167 static int hf_smb_server_cap_lock_and_read = -1;
168 static int hf_smb_server_cap_nt_find = -1;
169 static int hf_smb_server_cap_dfs = -1;
170 static int hf_smb_server_cap_infolevel_passthru = -1;
171 static int hf_smb_server_cap_large_readx = -1;
172 static int hf_smb_server_cap_large_writex = -1;
173 static int hf_smb_server_cap_unix = -1;
174 static int hf_smb_server_cap_reserved = -1;
175 static int hf_smb_server_cap_bulk_transfer = -1;
176 static int hf_smb_server_cap_compressed_data = -1;
177 static int hf_smb_server_cap_extended_security = -1;
178 static int hf_smb_system_time = -1;
179 static int hf_smb_unknown = -1;
180 static int hf_smb_dir_name = -1;
181 static int hf_smb_echo_count = -1;
182 static int hf_smb_echo_data = -1;
183 static int hf_smb_echo_seq_num = -1;
184 static int hf_smb_max_buf_size = -1;
185 static int hf_smb_password = -1;
186 static int hf_smb_password_len = -1;
187 static int hf_smb_ansi_password = -1;
188 static int hf_smb_ansi_password_len = -1;
189 static int hf_smb_unicode_password = -1;
190 static int hf_smb_unicode_password_len = -1;
191 static int hf_smb_path = -1;
192 static int hf_smb_service = -1;
193 static int hf_smb_move_flags_file = -1;
194 static int hf_smb_move_flags_dir = -1;
195 static int hf_smb_move_flags_verify = -1;
196 static int hf_smb_files_moved = -1;
197 static int hf_smb_copy_flags_file = -1;
198 static int hf_smb_copy_flags_dir = -1;
199 static int hf_smb_copy_flags_dest_mode = -1;
200 static int hf_smb_copy_flags_source_mode = -1;
201 static int hf_smb_copy_flags_verify = -1;
202 static int hf_smb_copy_flags_tree_copy = -1;
203 static int hf_smb_copy_flags_ea_action = -1;
204 static int hf_smb_count = -1;
205 static int hf_smb_count_low = -1;
206 static int hf_smb_count_high = -1;
207 static int hf_smb_file_name = -1;
208 static int hf_smb_open_function_open = -1;
209 static int hf_smb_open_function_create = -1;
210 static int hf_smb_fid = -1;
211 static int hf_smb_file_attr_read_only_16bit = -1;
212 static int hf_smb_file_attr_read_only_8bit = -1;
213 static int hf_smb_file_attr_hidden_16bit = -1;
214 static int hf_smb_file_attr_hidden_8bit = -1;
215 static int hf_smb_file_attr_system_16bit = -1;
216 static int hf_smb_file_attr_system_8bit = -1;
217 static int hf_smb_file_attr_volume_16bit = -1;
218 static int hf_smb_file_attr_volume_8bit = -1;
219 static int hf_smb_file_attr_directory_16bit = -1;
220 static int hf_smb_file_attr_directory_8bit = -1;
221 static int hf_smb_file_attr_archive_16bit = -1;
222 static int hf_smb_file_attr_archive_8bit = -1;
223 static int hf_smb_file_attr_device = -1;
224 static int hf_smb_file_attr_normal = -1;
225 static int hf_smb_file_attr_temporary = -1;
226 static int hf_smb_file_attr_sparse = -1;
227 static int hf_smb_file_attr_reparse = -1;
228 static int hf_smb_file_attr_compressed = -1;
229 static int hf_smb_file_attr_offline = -1;
230 static int hf_smb_file_attr_not_content_indexed = -1;
231 static int hf_smb_file_attr_encrypted = -1;
232 static int hf_smb_file_size = -1;
233 static int hf_smb_search_attribute_read_only = -1;
234 static int hf_smb_search_attribute_hidden = -1;
235 static int hf_smb_search_attribute_system = -1;
236 static int hf_smb_search_attribute_volume = -1;
237 static int hf_smb_search_attribute_directory = -1;
238 static int hf_smb_search_attribute_archive = -1;
239 static int hf_smb_access_mode = -1;
240 static int hf_smb_access_sharing = -1;
241 static int hf_smb_access_locality = -1;
242 static int hf_smb_access_caching = -1;
243 static int hf_smb_access_writetru = -1;
244 static int hf_smb_create_time = -1;
245 static int hf_smb_modify_time = -1;
246 static int hf_smb_backup_time = -1;
247 static int hf_smb_mac_alloc_block_count = -1;
248 static int hf_smb_mac_alloc_block_size = -1;
249 static int hf_smb_mac_free_block_count = -1;
250 static int hf_smb_mac_fndrinfo = -1;
251 static int hf_smb_mac_root_file_count = -1;
252 static int hf_smb_mac_root_dir_count = -1;
253 static int hf_smb_mac_file_count = -1;
254 static int hf_smb_mac_dir_count = -1;
255 static int hf_smb_mac_support_flags = -1;
256 static int hf_smb_mac_sup_access_ctrl = -1;
257 static int hf_smb_mac_sup_getset_comments = -1;
258 static int hf_smb_mac_sup_desktopdb_calls = -1;
259 static int hf_smb_mac_sup_unique_ids = -1;
260 static int hf_smb_mac_sup_streams = -1;
261 static int hf_smb_create_dos_date = -1;
262 static int hf_smb_create_dos_time = -1;
263 static int hf_smb_last_write_time = -1;
264 static int hf_smb_last_write_dos_date = -1;
265 static int hf_smb_last_write_dos_time = -1;
266 static int hf_smb_access_time = -1;
267 static int hf_smb_access_dos_date = -1;
268 static int hf_smb_access_dos_time = -1;
269 static int hf_smb_old_file_name = -1;
270 static int hf_smb_offset = -1;
271 static int hf_smb_remaining = -1;
272 static int hf_smb_padding = -1;
273 static int hf_smb_file_data = -1;
274 static int hf_smb_total_data_len = -1;
275 static int hf_smb_data_len = -1;
276 static int hf_smb_data_len_low = -1;
277 static int hf_smb_data_len_high = -1;
278 static int hf_smb_seek_mode = -1;
279 static int hf_smb_data_size = -1;
280 static int hf_smb_alloc_size = -1;
281 static int hf_smb_alloc_size64 = -1;
282 static int hf_smb_max_count = -1;
283 static int hf_smb_max_count_low = -1;
284 static int hf_smb_max_count_high = -1;
285 static int hf_smb_min_count = -1;
286 static int hf_smb_timeout = -1;
287 static int hf_smb_high_offset = -1;
288 static int hf_smb_units = -1;
289 static int hf_smb_bpu = -1;
290 static int hf_smb_blocksize = -1;
291 static int hf_smb_freeunits = -1;
292 static int hf_smb_data_offset = -1;
293 static int hf_smb_dcm = -1;
294 static int hf_smb_request_mask = -1;
295 static int hf_smb_response_mask = -1;
296 static int hf_smb_search_id = -1;
297 static int hf_smb_write_mode_write_through = -1;
298 static int hf_smb_write_mode_return_remaining = -1;
299 static int hf_smb_write_mode_raw = -1;
300 static int hf_smb_write_mode_message_start = -1;
301 static int hf_smb_write_mode_connectionless = -1;
302 static int hf_smb_resume_key_len = -1;
303 static int hf_smb_resume_find_id = -1;
304 static int hf_smb_resume_server_cookie = -1;
305 static int hf_smb_resume_client_cookie = -1;
306 static int hf_smb_andxoffset = -1;
307 static int hf_smb_lock_type_large = -1;
308 static int hf_smb_lock_type_cancel = -1;
309 static int hf_smb_lock_type_change = -1;
310 static int hf_smb_lock_type_oplock = -1;
311 static int hf_smb_lock_type_shared = -1;
312 static int hf_smb_locking_ol = -1;
313 static int hf_smb_number_of_locks = -1;
314 static int hf_smb_number_of_unlocks = -1;
315 static int hf_smb_lock_long_offset = -1;
316 static int hf_smb_lock_long_length = -1;
317 static int hf_smb_file_type = -1;
318 static int hf_smb_ipc_state_nonblocking = -1;
319 static int hf_smb_ipc_state_endpoint = -1;
320 static int hf_smb_ipc_state_pipe_type = -1;
321 static int hf_smb_ipc_state_read_mode = -1;
322 static int hf_smb_ipc_state_icount = -1;
323 static int hf_smb_server_fid = -1;
324 static int hf_smb_open_flags_add_info = -1;
325 static int hf_smb_open_flags_ex_oplock = -1;
326 static int hf_smb_open_flags_batch_oplock = -1;
327 static int hf_smb_open_flags_ealen = -1;
328 static int hf_smb_open_action_open = -1;
329 static int hf_smb_open_action_lock = -1;
330 static int hf_smb_vc_num = -1;
331 static int hf_smb_account = -1;
332 static int hf_smb_os = -1;
333 static int hf_smb_lanman = -1;
334 static int hf_smb_setup_action_guest = -1;
335 static int hf_smb_fs = -1;
336 static int hf_smb_connect_flags_dtid = -1;
337 static int hf_smb_connect_support_search = -1;
338 static int hf_smb_connect_support_in_dfs = -1;
339 static int hf_smb_max_setup_count = -1;
340 static int hf_smb_total_param_count = -1;
341 static int hf_smb_total_data_count = -1;
342 static int hf_smb_max_param_count = -1;
343 static int hf_smb_max_data_count = -1;
344 static int hf_smb_param_disp16 = -1;
345 static int hf_smb_param_count16 = -1;
346 static int hf_smb_param_offset16 = -1;
347 static int hf_smb_param_disp32 = -1;
348 static int hf_smb_param_count32 = -1;
349 static int hf_smb_param_offset32 = -1;
350 static int hf_smb_data_disp16 = -1;
351 static int hf_smb_data_count16 = -1;
352 static int hf_smb_data_offset16 = -1;
353 static int hf_smb_data_disp32 = -1;
354 static int hf_smb_data_count32 = -1;
355 static int hf_smb_data_offset32 = -1;
356 static int hf_smb_setup_count = -1;
357 static int hf_smb_nt_trans_subcmd = -1;
358 static int hf_smb_nt_ioctl_function_code = -1;
359 static int hf_smb_nt_ioctl_isfsctl = -1;
360 static int hf_smb_nt_ioctl_flags_root_handle = -1;
361 static int hf_smb_nt_ioctl_data = -1;
362 #ifdef SMB_UNUSED_HANDLES
363 static int hf_smb_nt_security_information = -1;
364 #endif
365 static int hf_smb_nt_notify_action = -1;
366 static int hf_smb_nt_notify_watch_tree = -1;
367 static int hf_smb_nt_notify_stream_write = -1;
368 static int hf_smb_nt_notify_stream_size = -1;
369 static int hf_smb_nt_notify_stream_name = -1;
370 static int hf_smb_nt_notify_security = -1;
371 static int hf_smb_nt_notify_ea = -1;
372 static int hf_smb_nt_notify_creation = -1;
373 static int hf_smb_nt_notify_last_access = -1;
374 static int hf_smb_nt_notify_last_write = -1;
375 static int hf_smb_nt_notify_size = -1;
376 static int hf_smb_nt_notify_attributes = -1;
377 static int hf_smb_nt_notify_dir_name = -1;
378 static int hf_smb_nt_notify_file_name = -1;
379 static int hf_smb_root_dir_fid = -1;
380 static int hf_smb_nt_create_disposition = -1;
381 static int hf_smb_sd_length = -1;
382 static int hf_smb_ea_list_length = -1;
383 static int hf_smb_ea_flags = -1;
384 static int hf_smb_ea_name_length = -1;
385 static int hf_smb_ea_data_length = -1;
386 static int hf_smb_ea_name = -1;
387 static int hf_smb_ea_data = -1;
388 static int hf_smb_file_name_len = -1;
389 static int hf_smb_nt_impersonation_level = -1;
390 static int hf_smb_nt_security_flags_context_tracking = -1;
391 static int hf_smb_nt_security_flags_effective_only = -1;
392 static int hf_smb_nt_access_mask_generic_read = -1;
393 static int hf_smb_nt_access_mask_generic_write = -1;
394 static int hf_smb_nt_access_mask_generic_execute = -1;
395 static int hf_smb_nt_access_mask_generic_all = -1;
396 static int hf_smb_nt_access_mask_maximum_allowed = -1;
397 static int hf_smb_nt_access_mask_system_security = -1;
398 static int hf_smb_nt_access_mask_synchronize = -1;
399 static int hf_smb_nt_access_mask_write_owner = -1;
400 static int hf_smb_nt_access_mask_write_dac = -1;
401 static int hf_smb_nt_access_mask_read_control = -1;
402 static int hf_smb_nt_access_mask_delete = -1;
403 static int hf_smb_nt_access_mask_write_attributes = -1;
404 static int hf_smb_nt_access_mask_read_attributes = -1;
405 static int hf_smb_nt_access_mask_delete_child = -1;
406 static int hf_smb_nt_access_mask_execute = -1;
407 static int hf_smb_nt_access_mask_write_ea = -1;
408 static int hf_smb_nt_access_mask_read_ea = -1;
409 static int hf_smb_nt_access_mask_append = -1;
410 static int hf_smb_nt_access_mask_write = -1;
411 static int hf_smb_nt_access_mask_read = -1;
412 static int hf_smb_nt_create_bits_oplock = -1;
413 static int hf_smb_nt_create_bits_boplock = -1;
414 static int hf_smb_nt_create_bits_dir = -1;
415 static int hf_smb_nt_create_bits_ext_resp = -1;
416 static int hf_smb_nt_create_options_directory_file = -1;
417 static int hf_smb_nt_create_options_write_through = -1;
418 static int hf_smb_nt_create_options_sequential_only = -1;
419 static int hf_smb_nt_create_options_sync_io_alert = -1;
420 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
421 static int hf_smb_nt_create_options_non_directory_file = -1;
422 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
423 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
424 static int hf_smb_nt_create_options_random_access = -1;
425 static int hf_smb_nt_create_options_delete_on_close = -1;
426 static int hf_smb_nt_share_access_read = -1;
427 static int hf_smb_nt_share_access_write = -1;
428 static int hf_smb_nt_share_access_delete = -1;
429 static int hf_smb_file_eattr_read_only = -1;
430 static int hf_smb_file_eattr_hidden = -1;
431 static int hf_smb_file_eattr_system = -1;
432 static int hf_smb_file_eattr_volume = -1;
433 static int hf_smb_file_eattr_directory = -1;
434 static int hf_smb_file_eattr_archive = -1;
435 static int hf_smb_file_eattr_device = -1;
436 static int hf_smb_file_eattr_normal = -1;
437 static int hf_smb_file_eattr_temporary = -1;
438 static int hf_smb_file_eattr_sparse = -1;
439 static int hf_smb_file_eattr_reparse = -1;
440 static int hf_smb_file_eattr_compressed = -1;
441 static int hf_smb_file_eattr_offline = -1;
442 static int hf_smb_file_eattr_not_content_indexed = -1;
443 static int hf_smb_file_eattr_encrypted = -1;
444 static int hf_smb_sec_desc_len = -1;
445 static int hf_smb_sec_desc_revision = -1;
446 static int hf_smb_sec_desc_type_owner_defaulted = -1;
447 static int hf_smb_sec_desc_type_group_defaulted = -1;
448 static int hf_smb_sec_desc_type_dacl_present = -1;
449 static int hf_smb_sec_desc_type_dacl_defaulted = -1;
450 static int hf_smb_sec_desc_type_sacl_present = -1;
451 static int hf_smb_sec_desc_type_sacl_defaulted = -1;
452 static int hf_smb_sec_desc_type_dacl_auto_inherit_req = -1;
453 static int hf_smb_sec_desc_type_sacl_auto_inherit_req = -1;
454 static int hf_smb_sec_desc_type_dacl_auto_inherited = -1;
455 static int hf_smb_sec_desc_type_sacl_auto_inherited = -1;
456 static int hf_smb_sec_desc_type_dacl_protected = -1;
457 static int hf_smb_sec_desc_type_sacl_protected = -1;
458 static int hf_smb_sec_desc_type_self_relative = -1;
459 static int hf_smb_sid = -1;
460 static int hf_smb_sid_revision = -1;
461 static int hf_smb_sid_num_auth = -1;
462 static int hf_smb_acl_revision = -1;
463 static int hf_smb_acl_size = -1;
464 static int hf_smb_acl_num_aces = -1;
465 static int hf_smb_ace_type = -1;
466 static int hf_smb_ace_size = -1;
467 static int hf_smb_ace_flags_object_inherit = -1;
468 static int hf_smb_ace_flags_container_inherit = -1;
469 static int hf_smb_ace_flags_non_propagate_inherit = -1;
470 static int hf_smb_ace_flags_inherit_only = -1;
471 static int hf_smb_ace_flags_inherited_ace = -1;
472 static int hf_smb_ace_flags_successful_access = -1;
473 static int hf_smb_ace_flags_failed_access = -1;
474 static int hf_smb_nt_qsd_owner = -1;
475 static int hf_smb_nt_qsd_group = -1;
476 static int hf_smb_nt_qsd_dacl = -1;
477 static int hf_smb_nt_qsd_sacl = -1;
478 static int hf_smb_extended_attributes = -1;
479 static int hf_smb_oplock_level = -1;
480 static int hf_smb_create_action = -1;
481 static int hf_smb_file_id = -1;
482 static int hf_smb_ea_error_offset = -1;
483 static int hf_smb_end_of_file = -1;
484 static int hf_smb_device_type = -1;
485 static int hf_smb_is_directory = -1;
486 static int hf_smb_next_entry_offset = -1;
487 static int hf_smb_change_time = -1;
488 static int hf_smb_setup_len = -1;
489 static int hf_smb_print_mode = -1;
490 static int hf_smb_print_identifier = -1;
491 static int hf_smb_restart_index = -1;
492 static int hf_smb_print_queue_date = -1;
493 static int hf_smb_print_queue_dos_date = -1;
494 static int hf_smb_print_queue_dos_time = -1;
495 static int hf_smb_print_status = -1;
496 static int hf_smb_print_spool_file_number = -1;
497 static int hf_smb_print_spool_file_size = -1;
498 static int hf_smb_print_spool_file_name = -1;
499 static int hf_smb_start_index = -1;
500 static int hf_smb_originator_name = -1;
501 static int hf_smb_destination_name = -1;
502 static int hf_smb_message_len = -1;
503 static int hf_smb_message = -1;
504 static int hf_smb_mgid = -1;
505 static int hf_smb_forwarded_name = -1;
506 static int hf_smb_machine_name = -1;
507 static int hf_smb_cancel_to = -1;
508 static int hf_smb_trans2_subcmd = -1;
509 static int hf_smb_trans_name = -1;
510 static int hf_smb_transaction_flags_dtid = -1;
511 static int hf_smb_transaction_flags_owt = -1;
512 static int hf_smb_search_count = -1;
513 static int hf_smb_search_pattern = -1;
514 static int hf_smb_ff2_backup = -1;
515 static int hf_smb_ff2_continue = -1;
516 static int hf_smb_ff2_resume = -1;
517 static int hf_smb_ff2_close_eos = -1;
518 static int hf_smb_ff2_close = -1;
519 static int hf_smb_ff2_information_level = -1;
520 static int hf_smb_qpi_loi = -1;
521 static int hf_smb_spi_loi = -1;
522 #if 0
523 static int hf_smb_sfi_writetru = -1;
524 static int hf_smb_sfi_caching = -1;
525 #endif
526 static int hf_smb_storage_type = -1;
527 static int hf_smb_resume = -1;
528 static int hf_smb_max_referral_level = -1;
529 static int hf_smb_qfsi_information_level = -1;
530 static int hf_smb_number_of_links = -1;
531 static int hf_smb_delete_pending = -1;
532 static int hf_smb_index_number = -1;
533 static int hf_smb_current_offset = -1;
534 static int hf_smb_t2_alignment = -1;
535 static int hf_smb_t2_stream_name_length = -1;
536 static int hf_smb_t2_stream_size = -1;
537 static int hf_smb_t2_stream_name = -1;
538 static int hf_smb_t2_compressed_file_size = -1;
539 static int hf_smb_t2_compressed_format = -1;
540 static int hf_smb_t2_compressed_unit_shift = -1;
541 static int hf_smb_t2_compressed_chunk_shift = -1;
542 static int hf_smb_t2_compressed_cluster_shift = -1;
543 static int hf_smb_t2_marked_for_deletion = -1;
544 static int hf_smb_dfs_path_consumed = -1;
545 static int hf_smb_dfs_num_referrals = -1;
546 static int hf_smb_get_dfs_server_hold_storage = -1;
547 static int hf_smb_get_dfs_fielding = -1;
548 static int hf_smb_dfs_referral_version = -1;
549 static int hf_smb_dfs_referral_size = -1;
550 static int hf_smb_dfs_referral_server_type = -1;
551 static int hf_smb_dfs_referral_flags_strip = -1;
552 static int hf_smb_dfs_referral_node_offset = -1;
553 static int hf_smb_dfs_referral_node = -1;
554 static int hf_smb_dfs_referral_proximity = -1;
555 static int hf_smb_dfs_referral_ttl = -1;
556 static int hf_smb_dfs_referral_path_offset = -1;
557 static int hf_smb_dfs_referral_path = -1;
558 static int hf_smb_dfs_referral_alt_path_offset = -1;
559 static int hf_smb_dfs_referral_alt_path = -1;
560 static int hf_smb_end_of_search = -1;
561 static int hf_smb_last_name_offset = -1;
562 static int hf_smb_fn_information_level = -1;
563 static int hf_smb_monitor_handle = -1;
564 static int hf_smb_change_count = -1;
565 static int hf_smb_file_index = -1;
566 static int hf_smb_short_file_name = -1;
567 static int hf_smb_short_file_name_len = -1;
568 static int hf_smb_fs_id = -1;
569 static int hf_smb_fs_guid = -1;
570 static int hf_smb_sector_unit = -1;
571 static int hf_smb_fs_units = -1;
572 static int hf_smb_fs_sector = -1;
573 static int hf_smb_avail_units = -1;
574 static int hf_smb_volume_serial_num = -1;
575 static int hf_smb_volume_label_len = -1;
576 static int hf_smb_volume_label = -1;
577 static int hf_smb_free_alloc_units64 = -1;
578 static int hf_smb_caller_free_alloc_units64 = -1;
579 static int hf_smb_actual_free_alloc_units64 = -1;
580 static int hf_smb_max_name_len = -1;
581 static int hf_smb_fs_name_len = -1;
582 static int hf_smb_fs_name = -1;
583 static int hf_smb_device_char_removable = -1;
584 static int hf_smb_device_char_read_only = -1;
585 static int hf_smb_device_char_floppy = -1;
586 static int hf_smb_device_char_write_once = -1;
587 static int hf_smb_device_char_remote = -1;
588 static int hf_smb_device_char_mounted = -1;
589 static int hf_smb_device_char_virtual = -1;
590 static int hf_smb_fs_attr_css = -1;
591 static int hf_smb_fs_attr_cpn = -1;
592 static int hf_smb_fs_attr_pacls = -1;
593 static int hf_smb_fs_attr_fc = -1;
594 static int hf_smb_fs_attr_vq = -1;
595 static int hf_smb_fs_attr_dim = -1;
596 static int hf_smb_fs_attr_vic = -1;
597 static int hf_smb_quota_flags_enabled = -1;
598 static int hf_smb_quota_flags_deny_disk = -1;
599 static int hf_smb_quota_flags_log_limit = -1;
600 static int hf_smb_quota_flags_log_warning = -1;
601 static int hf_smb_soft_quota_limit = -1;
602 static int hf_smb_hard_quota_limit = -1;
603 static int hf_smb_user_quota_used = -1;
604 static int hf_smb_user_quota_offset = -1;
605 static int hf_smb_nt_rename_level = -1;
606 static int hf_smb_cluster_count = -1;
607 static int hf_smb_segments = -1;
608 static int hf_smb_segment = -1;
609 static int hf_smb_segment_overlap = -1;
610 static int hf_smb_segment_overlap_conflict = -1;
611 static int hf_smb_segment_multiple_tails = -1;
612 static int hf_smb_segment_too_long_fragment = -1;
613 static int hf_smb_segment_error = -1;
614 static int hf_smb_pipe_write_len = -1;
615 static int hf_smb_unix_major_version = -1;
616 static int hf_smb_unix_minor_version = -1;
617 static int hf_smb_unix_capability_fcntl = -1;
618 static int hf_smb_unix_capability_posix_acl = -1;
619 static int hf_smb_unix_file_size = -1;
620 static int hf_smb_unix_file_num_bytes = -1;
621 static int hf_smb_unix_file_last_status = -1;
622 static int hf_smb_unix_file_last_access = -1;
623 static int hf_smb_unix_file_last_change = -1;
624 static int hf_smb_unix_file_uid = -1;
625 static int hf_smb_unix_file_gid = -1;
626 static int hf_smb_unix_file_type = -1;
627 static int hf_smb_unix_file_dev_major = -1;
628 static int hf_smb_unix_file_dev_minor = -1;
629 static int hf_smb_unix_file_unique_id = -1;
630 static int hf_smb_unix_file_permissions = -1;
631 static int hf_smb_unix_file_nlinks = -1;
632 static int hf_smb_unix_file_link_dest = -1;
633 static int hf_smb_unix_find_file_nextoffset = -1;
634 static int hf_smb_unix_find_file_resumekey = -1;
635
636 static gint ett_smb = -1;
637 static gint ett_smb_hdr = -1;
638 static gint ett_smb_command = -1;
639 static gint ett_smb_fileattributes = -1;
640 static gint ett_smb_capabilities = -1;
641 static gint ett_smb_aflags = -1;
642 static gint ett_smb_dialect = -1;
643 static gint ett_smb_dialects = -1;
644 static gint ett_smb_mode = -1;
645 static gint ett_smb_rawmode = -1;
646 static gint ett_smb_flags = -1;
647 static gint ett_smb_flags2 = -1;
648 static gint ett_smb_desiredaccess = -1;
649 static gint ett_smb_search = -1;
650 static gint ett_smb_file = -1;
651 static gint ett_smb_openfunction = -1;
652 static gint ett_smb_filetype = -1;
653 static gint ett_smb_openaction = -1;
654 static gint ett_smb_writemode = -1;
655 static gint ett_smb_lock_type = -1;
656 static gint ett_smb_ssetupandxaction = -1;
657 static gint ett_smb_optionsup = -1;
658 static gint ett_smb_time_date = -1;
659 static gint ett_smb_move_copy_flags = -1;
660 static gint ett_smb_file_attributes = -1;
661 static gint ett_smb_search_resume_key = -1;
662 static gint ett_smb_search_dir_info = -1;
663 static gint ett_smb_unlocks = -1;
664 static gint ett_smb_unlock = -1;
665 static gint ett_smb_locks = -1;
666 static gint ett_smb_lock = -1;
667 static gint ett_smb_open_flags = -1;
668 static gint ett_smb_ipc_state = -1;
669 static gint ett_smb_open_action = -1;
670 static gint ett_smb_setup_action = -1;
671 static gint ett_smb_connect_flags = -1;
672 static gint ett_smb_connect_support_bits = -1;
673 static gint ett_smb_nt_access_mask = -1;
674 static gint ett_smb_nt_create_bits = -1;
675 static gint ett_smb_nt_create_options = -1;
676 static gint ett_smb_nt_share_access = -1;
677 static gint ett_smb_nt_security_flags = -1;
678 static gint ett_smb_nt_trans_setup = -1;
679 static gint ett_smb_nt_trans_data = -1;
680 static gint ett_smb_nt_trans_param = -1;
681 static gint ett_smb_nt_notify_completion_filter = -1;
682 static gint ett_smb_nt_ioctl_flags = -1;
683 static gint ett_smb_security_information_mask = -1;
684 static gint ett_smb_print_queue_entry = -1;
685 static gint ett_smb_transaction_flags = -1;
686 static gint ett_smb_transaction_params = -1;
687 static gint ett_smb_find_first2_flags = -1;
688 static gint ett_smb_mac_support_flags = -1;
689 #if 0
690 static gint ett_smb_ioflag = -1;
691 #endif
692 static gint ett_smb_transaction_data = -1;
693 static gint ett_smb_stream_info = -1;
694 static gint ett_smb_dfs_referrals = -1;
695 static gint ett_smb_dfs_referral = -1;
696 static gint ett_smb_dfs_referral_flags = -1;
697 static gint ett_smb_get_dfs_flags = -1;
698 static gint ett_smb_ff2_data = -1;
699 static gint ett_smb_device_characteristics = -1;
700 static gint ett_smb_fs_attributes = -1;
701 static gint ett_smb_segments = -1;
702 static gint ett_smb_segment = -1;
703 static gint ett_smb_sec_desc = -1;
704 static gint ett_smb_sid = -1;
705 static gint ett_smb_acl = -1;
706 static gint ett_smb_ace = -1;
707 static gint ett_smb_ace_flags = -1;
708 static gint ett_smb_sec_desc_type = -1;
709 static gint ett_smb_quotaflags = -1;
710 static gint ett_smb_secblob = -1;
711 static gint ett_smb_unicode_password = -1;
712 static gint ett_smb_ea = -1;
713 static gint ett_smb_unix_capabilities = -1;
714
715 static int smb_tap = -1;
716
717 static dissector_handle_t gssapi_handle = NULL;
718 static dissector_handle_t ntlmssp_handle = NULL;
719
720 static const fragment_items smb_frag_items = {
721         &ett_smb_segment,
722         &ett_smb_segments,
723
724         &hf_smb_segments,
725         &hf_smb_segment,
726         &hf_smb_segment_overlap,
727         &hf_smb_segment_overlap_conflict,
728         &hf_smb_segment_multiple_tails,
729         &hf_smb_segment_too_long_fragment,
730         &hf_smb_segment_error,
731         NULL,
732
733         "segments"
734 };
735
736 proto_tree *top_tree=NULL;     /* ugly */
737
738 static char *decode_smb_name(unsigned char);
739 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu);
740
741 /*
742  * Macros for use in the main dissector routines for an SMB.
743  */
744
745 #define WORD_COUNT      \
746         /* Word Count */                                \
747         wc = tvb_get_guint8(tvb, offset);               \
748         proto_tree_add_uint(tree, hf_smb_word_count,    \
749                 tvb, offset, 1, wc);                    \
750         offset += 1;                                    \
751         if(wc==0) goto bytecount;
752
753 #define BYTE_COUNT      \
754         bytecount:                                      \
755         bc = tvb_get_letohs(tvb, offset);               \
756         proto_tree_add_uint(tree, hf_smb_byte_count,    \
757                         tvb, offset, 2, bc);            \
758         offset += 2;                                    \
759         if(bc==0) goto endofcommand;
760
761 #define CHECK_BYTE_COUNT(len)   \
762         if (bc < len) goto endofcommand;
763
764 #define COUNT_BYTES(len)   {\
765         int tmp;            \
766         tmp=len;            \
767         offset += tmp;      \
768         bc -= tmp;          \
769         }
770
771 #define END_OF_SMB      \
772         if (bc != 0) { \
773                 proto_tree_add_text(tree, tvb, offset, bc, \
774                     "Extra byte parameters");           \
775                 offset += bc;                           \
776         }                                               \
777         endofcommand:
778
779 /*
780  * Macros for use in routines called by them.
781  */
782 #define CHECK_BYTE_COUNT_SUBR(len)      \
783         if (*bcp < len) {               \
784                 *trunc = TRUE;          \
785                 return offset;          \
786         }
787
788 #define CHECK_STRING_SUBR(fn)   \
789         if (fn == NULL) {       \
790                 *trunc = TRUE;  \
791                 return offset;  \
792         }
793
794 #define COUNT_BYTES_SUBR(len)   \
795         offset += len;          \
796         *bcp -= len;
797
798 /*
799  * Macros for use when dissecting transaction parameters and data
800  */
801 #define CHECK_BYTE_COUNT_TRANS(len)     \
802         if (bc < len) return offset;
803
804 #define CHECK_STRING_TRANS(fn)  \
805         if (fn == NULL) return offset;
806
807 #define COUNT_BYTES_TRANS(len)  \
808         offset += len;          \
809         bc -= len;
810
811 /*
812  * Macros for use in subrroutines dissecting transaction parameters or data
813  */
814 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
815         if (*bcp < len) return offset;
816
817 #define CHECK_STRING_TRANS_SUBR(fn)     \
818         if (fn == NULL) return offset;
819
820 #define COUNT_BYTES_TRANS_SUBR(len)     \
821         offset += len;                  \
822         *bcp -= len;
823
824
825 gboolean sid_name_snooping = FALSE;
826
827 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
828    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
829    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
830 static gboolean smb_trans_reassembly = FALSE;
831 gboolean smb_dcerpc_reassembly = FALSE;
832
833 static GHashTable *smb_trans_fragment_table = NULL;
834
835 static void
836 smb_trans_reassembly_init(void)
837 {
838         fragment_table_init(&smb_trans_fragment_table);
839 }
840
841 static fragment_data *
842 smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
843                      int offset, int count, int pos, int totlen)
844 {
845         fragment_data *fd_head=NULL;
846         smb_info_t *si;
847         int more_frags;
848
849         more_frags=totlen>(pos+count);
850
851         si = (smb_info_t *)pinfo->private_data;
852         if (si->sip == NULL) {
853                 /*
854                  * We don't have the frame number of the request.
855                  *
856                  * XXX - is there truly nothing we can do here?
857                  * Can we not separately keep track of the original
858                  * transaction and its continuations, as we did
859                  * at one time?
860                  *
861                  * It is probably not much point in even trying to do something here
862                  * if we have never seen the initial request. Without the initial
863                  * request we probably miss all parameters and the begining of data
864                  * so we cant even call a subdissector since we can not determine
865                  * which type of transaction call this is.
866                  */
867                 return NULL;
868         }
869
870         if(!pinfo->fd->flags.visited){
871                 fd_head = fragment_add(tvb, offset, pinfo,
872                                        si->sip->frame_req, smb_trans_fragment_table,
873                                        pos, count, more_frags);
874         } else {
875                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
876         }
877
878         /* we only show the defragmented packet for the first fragment,
879            or else we might end up with dissecting one HUGE transaction PDU
880            a LOT of times. (first fragment is the only one containing the setup
881            bytes)
882            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction
883            SMBs. Takes a LOT of time dissecting and is not fun.
884         */
885         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
886                 return fd_head;
887         } else {
888                 return NULL;
889         }
890 }
891
892
893
894
895
896 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
897    These variables and functions are used to match
898    responses with calls
899    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
900 /*
901  * The information we need to save about a request in order to show the
902  * frame number of the request in the dissection of the reply.
903  */
904 typedef struct  {
905         guint32 frame;
906         guint32 pid_mid;
907 } smb_saved_info_key_t;
908
909 static GMemChunk *smb_saved_info_key_chunk = NULL;
910 static GMemChunk *smb_saved_info_chunk = NULL;
911 static int smb_saved_info_init_count = 200;
912
913 /* unmatched smb_saved_info structures.
914    For unmatched smb_saved_info structures we store the smb_saved_info
915    structure using the MID and the PID as the key.
916
917    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
918    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
919    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
920 */
921 static gint
922 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
923 {
924         register guint32 key1 = (guint32)k1;
925         register guint32 key2 = (guint32)k2;
926         return key1==key2;
927 }
928 static guint
929 smb_saved_info_hash_unmatched(gconstpointer k)
930 {
931         register guint32 key = (guint32)k;
932         return key;
933 }
934
935 /* matched smb_saved_info structures.
936    For matched smb_saved_info structures we store the smb_saved_info
937    structure twice in the table using the frame number, and a combination
938    of the MID and the PID, as the key.
939    The frame number is guaranteed to be unique but if ever someone makes
940    some change that will renumber the frames in a capture we are in BIG trouble.
941    This is not likely though since that would break (among other things) all the
942    reassembly routines as well.
943
944    We also need the MID as there may be more than one SMB request or reply
945    in a single frame, and we also need the PID as there may be more than
946    one outstanding request with the same MID and different PIDs.
947 */
948 static gint
949 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
950 {
951         const smb_saved_info_key_t *key1 = k1;
952         const smb_saved_info_key_t *key2 = k2;
953         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
954 }
955 static guint
956 smb_saved_info_hash_matched(gconstpointer k)
957 {
958         const smb_saved_info_key_t *key = k;
959         return key->frame + key->pid_mid;
960 }
961
962 static GMemChunk *smb_nt_transact_info_chunk = NULL;
963 static int smb_nt_transact_info_init_count = 200;
964
965 static GMemChunk *smb_transact2_info_chunk = NULL;
966 static int smb_transact2_info_init_count = 200;
967
968 /*
969  * The information we need to save about a Transaction request in order
970  * to dissect the reply; this includes information for use by the
971  * Remote API dissector.
972  */
973 static GMemChunk *smb_transact_info_chunk = NULL;
974 static int smb_transact_info_init_count = 200;
975
976 static GMemChunk *conv_tables_chunk = NULL;
977 static GSList *conv_tables = NULL;
978 static int conv_tables_count = 10;
979
980
981 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
982    End of request/response matching functions
983    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
984
985 static const value_string buffer_format_vals[] = {
986         {1,     "Data Block"},
987         {2,     "Dialect"},
988         {3,     "Pathname"},
989         {4,     "ASCII"},
990         {5,     "Variable Block"},
991         {0,     NULL}
992 };
993
994 /*
995  * UTIME - this is *almost* like a UNIX time stamp, except that it's
996  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
997  * January 1, 1970, 00:00:00 GMT.
998  *
999  * This means we have to do some extra work to convert it.  This code is
1000  * based on the Samba code:
1001  *
1002  *      Unix SMB/Netbios implementation.
1003  *      Version 1.9.
1004  *      time handling functions
1005  *      Copyright (C) Andrew Tridgell 1992-1998
1006  */
1007
1008 /*
1009  * Yield the difference between *A and *B, in seconds, ignoring leap
1010  * seconds.
1011  */
1012 #define TM_YEAR_BASE 1900
1013
1014 static int
1015 tm_diff(struct tm *a, struct tm *b)
1016 {
1017         int ay = a->tm_year + (TM_YEAR_BASE - 1);
1018         int by = b->tm_year + (TM_YEAR_BASE - 1);
1019         int intervening_leap_days =
1020             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
1021         int years = ay - by;
1022         int days =
1023             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
1024         int hours = 24*days + (a->tm_hour - b->tm_hour);
1025         int minutes = 60*hours + (a->tm_min - b->tm_min);
1026         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
1027
1028         return seconds;
1029 }
1030
1031 /*
1032  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
1033  * determined.
1034  */
1035 static int
1036 TimeZone(time_t t)
1037 {
1038         struct tm *tm = gmtime(&t);
1039         struct tm tm_utc;
1040
1041         if (tm == NULL)
1042                 return 0;
1043         tm_utc = *tm;
1044         tm = localtime(&t);
1045         if (tm == NULL)
1046                 return 0;
1047         return tm_diff(&tm_utc,tm);
1048 }
1049
1050 /*
1051  * Return the same value as TimeZone, but it should be more efficient.
1052  *
1053  * We keep a table of DST offsets to prevent calling localtime() on each
1054  * call of this function. This saves a LOT of time on many unixes.
1055  *
1056  * Updated by Paul Eggert <eggert@twinsun.com>
1057  */
1058 #ifndef CHAR_BIT
1059 #define CHAR_BIT 8
1060 #endif
1061
1062 #ifndef TIME_T_MIN
1063 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1064                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
1065 #endif
1066 #ifndef TIME_T_MAX
1067 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
1068 #endif
1069
1070 static int
1071 TimeZoneFaster(time_t t)
1072 {
1073         static struct dst_table {time_t start,end; int zone;} *tdt;
1074         static struct dst_table *dst_table = NULL;
1075         static int table_size = 0;
1076         int i;
1077         int zone = 0;
1078
1079         if (t == 0)
1080                 t = time(NULL);
1081
1082         /* Tunis has a 8 day DST region, we need to be careful ... */
1083 #define MAX_DST_WIDTH (365*24*60*60)
1084 #define MAX_DST_SKIP (7*24*60*60)
1085
1086         for (i = 0; i < table_size; i++) {
1087                 if (t >= dst_table[i].start && t <= dst_table[i].end)
1088                         break;
1089         }
1090
1091         if (i < table_size) {
1092                 zone = dst_table[i].zone;
1093         } else {
1094                 time_t low,high;
1095
1096                 zone = TimeZone(t);
1097                 if (dst_table == NULL)
1098                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1099                 else
1100                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1101                 if (tdt == NULL) {
1102                         if (dst_table)
1103                                 g_free(dst_table);
1104                         table_size = 0;
1105                 } else {
1106                         dst_table = tdt;
1107                         table_size++;
1108
1109                         dst_table[i].zone = zone;
1110                         dst_table[i].start = dst_table[i].end = t;
1111
1112                         /* no entry will cover more than 6 months */
1113                         low = t - MAX_DST_WIDTH/2;
1114                         if (t < low)
1115                                 low = TIME_T_MIN;
1116
1117                         high = t + MAX_DST_WIDTH/2;
1118                         if (high < t)
1119                                 high = TIME_T_MAX;
1120
1121                         /*
1122                          * Widen the new entry using two bisection searches.
1123                          */
1124                         while (low+60*60 < dst_table[i].start) {
1125                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1126                                         t = dst_table[i].start - MAX_DST_SKIP;
1127                                 else
1128                                         t = low + (dst_table[i].start-low)/2;
1129                                 if (TimeZone(t) == zone)
1130                                         dst_table[i].start = t;
1131                                 else
1132                                         low = t;
1133                         }
1134
1135                         while (high-60*60 > dst_table[i].end) {
1136                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1137                                         t = dst_table[i].end + MAX_DST_SKIP;
1138                                 else
1139                                         t = high - (high-dst_table[i].end)/2;
1140                                 if (TimeZone(t) == zone)
1141                                         dst_table[i].end = t;
1142                                 else
1143                                         high = t;
1144                         }
1145                 }
1146         }
1147         return zone;
1148 }
1149
1150 /*
1151  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1152  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1153  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1154  * daylight savings transitions because some local times are ambiguous.
1155  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1156  */
1157 static int
1158 LocTimeDiff(time_t lt)
1159 {
1160         int d = TimeZoneFaster(lt);
1161         time_t t = lt + d;
1162
1163         /* if overflow occurred, ignore all the adjustments so far */
1164         if (((t < lt) ^ (d < 0)))
1165                 t = lt;
1166
1167         /*
1168          * Now t should be close enough to the true UTC to yield the
1169          * right answer.
1170          */
1171         return TimeZoneFaster(t);
1172 }
1173
1174 static int
1175 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1176 {
1177         guint32 timeval;
1178         nstime_t ts;
1179
1180         timeval = tvb_get_letohl(tvb, offset);
1181         if (timeval == 0xffffffff) {
1182                 proto_tree_add_text(tree, tvb, offset, 4,
1183                     "%s: No time specified (0xffffffff)",
1184                     proto_registrar_get_name(hf_date));
1185                 offset += 4;
1186                 return offset;
1187         }
1188
1189         /*
1190          * We add the local time offset.
1191          */
1192         ts.secs = timeval + LocTimeDiff(timeval);
1193         ts.nsecs = 0;
1194
1195         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1196         offset += 4;
1197
1198         return offset;
1199 }
1200
1201 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
1202
1203 /*
1204  * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits,
1205  * to an "nstime_t".
1206  * A FILETIME is a 64-bit integer, giving the time since Jan 1, 1601,
1207  * midnight "UTC", in 100ns units.
1208  * Return TRUE if the conversion succeeds, FALSE otherwise.
1209  *
1210  * According to the Samba code, it appears to be kludge-GMT (at least for
1211  * file listings). This means it's the GMT you get by taking a local time
1212  * and adding the server time zone offset.  This is NOT the same as GMT in
1213  * some cases.   However, we don't know the server time zone, so we don't
1214  * do that adjustment.
1215  *
1216  * This code is based on the Samba code:
1217  *
1218  *      Unix SMB/Netbios implementation.
1219  *      Version 1.9.
1220  *      time handling functions
1221  *      Copyright (C) Andrew Tridgell 1992-1998
1222  */
1223 static gboolean
1224 nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
1225 {
1226         double d;
1227         /* The next two lines are a fix needed for the
1228             broken SCO compiler. JRA. */
1229         time_t l_time_min = TIME_T_MIN;
1230         time_t l_time_max = TIME_T_MAX;
1231
1232         if (filetime_high == 0)
1233                 return FALSE;
1234
1235         /*
1236          * Get the time as a double, in seconds and fractional seconds.
1237          */
1238         d = ((double)filetime_high)*4.0*(double)(1<<30);
1239         d += filetime_low;
1240         d *= 1.0e-7;
1241
1242         /* Now adjust by 369 years, to make the seconds since 1970. */
1243         d -= TIME_FIXUP_CONSTANT;
1244
1245         if (!(l_time_min <= d && d <= l_time_max))
1246                 return FALSE;
1247
1248         /*
1249          * Get the time as seconds and nanoseconds.
1250          */
1251         tv->secs = d;
1252         tv->nsecs = (d - tv->secs)*1000000000;
1253
1254         return TRUE;
1255 }
1256
1257 int
1258 dissect_smb_64bit_time(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1259 {
1260         guint32 filetime_high, filetime_low;
1261         nstime_t ts;
1262
1263         /* XXX there seems also to be another special time value which is fairly common :
1264            0x40000000 00000000
1265            the meaning of this one is yet unknown
1266         */
1267         if (tree) {
1268                 filetime_low = tvb_get_letohl(tvb, offset);
1269                 filetime_high = tvb_get_letohl(tvb, offset + 4);
1270                 if (filetime_low == 0 && filetime_high == 0) {
1271                         proto_tree_add_text(tree, tvb, offset, 8,
1272                             "%s: No time specified (0)",
1273                             proto_registrar_get_name(hf_date));
1274                 } else if(filetime_low==0 && filetime_high==0x80000000){
1275                         proto_tree_add_text(tree, tvb, offset, 8,
1276                             "%s: Infinity (relative time)",
1277                             proto_registrar_get_name(hf_date));
1278                 } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
1279                         proto_tree_add_text(tree, tvb, offset, 8,
1280                             "%s: Infinity (absolute time)",
1281                             proto_registrar_get_name(hf_date));
1282                 } else {
1283                         if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
1284                                 proto_tree_add_time(tree, hf_date, tvb,
1285                                     offset, 8, &ts);
1286                         } else {
1287                                 proto_tree_add_text(tree, tvb, offset, 8,
1288                                     "%s: Time can't be converted",
1289                                     proto_registrar_get_name(hf_date));
1290                         }
1291                 }
1292         }
1293
1294         offset += 8;
1295         return offset;
1296 }
1297
1298 static int
1299 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1300     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1301 {
1302         guint16 dos_time, dos_date;
1303         proto_item *item = NULL;
1304         proto_tree *tree = NULL;
1305         struct tm tm;
1306         time_t t;
1307         static const int mday_noleap[12] = {
1308                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1309         };
1310         static const int mday_leap[12] = {
1311                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1312         };
1313 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1314         nstime_t tv;
1315
1316         if (time_first) {
1317                 dos_time = tvb_get_letohs(tvb, offset);
1318                 dos_date = tvb_get_letohs(tvb, offset+2);
1319         } else {
1320                 dos_date = tvb_get_letohs(tvb, offset);
1321                 dos_time = tvb_get_letohs(tvb, offset+2);
1322         }
1323
1324         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1325             (dos_date == 0 && dos_time == 0)) {
1326                 /*
1327                  * No date/time specified.
1328                  */
1329                 if(parent_tree){
1330                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1331                             "%s: No time specified (0x%08x)",
1332                             proto_registrar_get_name(hf_date),
1333                             (dos_date << 16) | dos_time);
1334                 }
1335                 offset += 4;
1336                 return offset;
1337         }
1338
1339         tm.tm_sec = (dos_time&0x1f)*2;
1340         tm.tm_min = (dos_time>>5)&0x3f;
1341         tm.tm_hour = (dos_time>>11)&0x1f;
1342         tm.tm_mday = dos_date&0x1f;
1343         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1344         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1345         tm.tm_isdst = -1;
1346
1347         /*
1348          * Do some sanity checks before calling "mktime()";
1349          * "mktime()" doesn't do them, it "normalizes" out-of-range
1350          * values.
1351          */
1352         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1353            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1354            (ISLEAP(tm.tm_year + 1900) ?
1355              tm.tm_mday > mday_leap[tm.tm_mon] :
1356              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1357              (t = mktime(&tm)) == -1) {
1358                 /*
1359                  * Invalid date/time.
1360                  */
1361                 if (parent_tree) {
1362                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1363                             "%s: Invalid time",
1364                             proto_registrar_get_name(hf_date));
1365                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1366                         if (time_first) {
1367                                 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);
1368                                 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);
1369                         } else {
1370                                 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);
1371                                 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);
1372                         }
1373                 }
1374                 offset += 4;
1375                 return offset;
1376         }
1377
1378         tv.secs = t;
1379         tv.nsecs = 0;
1380
1381         if(parent_tree){
1382                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1383                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1384                 if (time_first) {
1385                         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);
1386                         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);
1387                 } else {
1388                         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);
1389                         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);
1390                 }
1391         }
1392
1393         offset += 4;
1394
1395         return offset;
1396 }
1397
1398
1399 static const value_string da_access_vals[] = {
1400         { 0,            "Open for reading"},
1401         { 1,            "Open for writing"},
1402         { 2,            "Open for reading and writing"},
1403         { 3,            "Open for execute"},
1404         {0, NULL}
1405 };
1406 static const value_string da_sharing_vals[] = {
1407         { 0,            "Compatibility mode"},
1408         { 1,            "Deny read/write/execute (exclusive)"},
1409         { 2,            "Deny write"},
1410         { 3,            "Deny read/execute"},
1411         { 4,            "Deny none"},
1412         {0, NULL}
1413 };
1414 static const value_string da_locality_vals[] = {
1415         { 0,            "Locality of reference unknown"},
1416         { 1,            "Mainly sequential access"},
1417         { 2,            "Mainly random access"},
1418         { 3,            "Random access with some locality"},
1419         {0, NULL}
1420 };
1421 static const true_false_string tfs_da_caching = {
1422         "Do not cache this file",
1423         "Caching permitted on this file"
1424 };
1425 static const true_false_string tfs_da_writetru = {
1426         "Write through enabled",
1427         "Write through disabled"
1428 };
1429 static int
1430 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, char *type)
1431 {
1432         guint16 mask;
1433         proto_item *item = NULL;
1434         proto_tree *tree = NULL;
1435
1436         mask = tvb_get_letohs(tvb, offset);
1437
1438         if(parent_tree){
1439                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1440                         "%s Access: 0x%04x", type, mask);
1441                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1442         }
1443
1444         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1445                 tvb, offset, 2, mask);
1446         proto_tree_add_boolean(tree, hf_smb_access_caching,
1447                 tvb, offset, 2, mask);
1448         proto_tree_add_uint(tree, hf_smb_access_locality,
1449                 tvb, offset, 2, mask);
1450         proto_tree_add_uint(tree, hf_smb_access_sharing,
1451                 tvb, offset, 2, mask);
1452         proto_tree_add_uint(tree, hf_smb_access_mode,
1453                 tvb, offset, 2, mask);
1454
1455         offset += 2;
1456
1457         return offset;
1458 }
1459
1460 #define SMB_FILE_ATTRIBUTE_READ_ONLY            0x00000001
1461 #define SMB_FILE_ATTRIBUTE_HIDDEN               0x00000002
1462 #define SMB_FILE_ATTRIBUTE_SYSTEM               0x00000004
1463 #define SMB_FILE_ATTRIBUTE_VOLUME               0x00000008
1464 #define SMB_FILE_ATTRIBUTE_DIRECTORY            0x00000010
1465 #define SMB_FILE_ATTRIBUTE_ARCHIVE              0x00000020
1466 #define SMB_FILE_ATTRIBUTE_DEVICE               0x00000040
1467 #define SMB_FILE_ATTRIBUTE_NORMAL               0x00000080
1468 #define SMB_FILE_ATTRIBUTE_TEMPORARY            0x00000100
1469 #define SMB_FILE_ATTRIBUTE_SPARSE               0x00000200
1470 #define SMB_FILE_ATTRIBUTE_REPARSE              0x00000400
1471 #define SMB_FILE_ATTRIBUTE_COMPRESSED           0x00000800
1472 #define SMB_FILE_ATTRIBUTE_OFFLINE              0x00001000
1473 #define SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
1474 #define SMB_FILE_ATTRIBUTE_ENCRYPTED            0x00004000
1475
1476 static const true_false_string tfs_file_attribute_read_only = {
1477         "This file is READ ONLY",
1478         "This file is NOT read only",
1479 };
1480 static const true_false_string tfs_file_attribute_hidden = {
1481         "This is a HIDDEN file",
1482         "This is NOT a hidden file"
1483 };
1484 static const true_false_string tfs_file_attribute_system = {
1485         "This is a SYSTEM file",
1486         "This is NOT a system file"
1487 };
1488 static const true_false_string tfs_file_attribute_volume = {
1489         "This is a VOLUME ID",
1490         "This is NOT a volume ID"
1491 };
1492 static const true_false_string tfs_file_attribute_directory = {
1493         "This is a DIRECTORY",
1494         "This is NOT a directory"
1495 };
1496 static const true_false_string tfs_file_attribute_archive = {
1497         "This file has been modified since last ARCHIVE",
1498         "This file has NOT been modified since last archive"
1499 };
1500 static const true_false_string tfs_file_attribute_device = {
1501         "This is a DEVICE",
1502         "This is NOT a device"
1503 };
1504 static const true_false_string tfs_file_attribute_normal = {
1505         "This file is an ordinary file",
1506         "This file has some attribute set"
1507 };
1508 static const true_false_string tfs_file_attribute_temporary = {
1509         "This is a TEMPORARY file",
1510         "This is NOT a temporary file"
1511 };
1512 static const true_false_string tfs_file_attribute_sparse = {
1513         "This is a SPARSE file",
1514         "This is NOT a sparse file"
1515 };
1516 static const true_false_string tfs_file_attribute_reparse = {
1517         "This file has an associated REPARSE POINT",
1518         "This file does NOT have an associated reparse point"
1519 };
1520 static const true_false_string tfs_file_attribute_compressed = {
1521         "This is a COMPRESSED file",
1522         "This is NOT a compressed file"
1523 };
1524 static const true_false_string tfs_file_attribute_offline = {
1525         "This file is OFFLINE",
1526         "This file is NOT offline"
1527 };
1528 static const true_false_string tfs_file_attribute_not_content_indexed = {
1529         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1530         "This file MAY be indexed by the content indexing service"
1531 };
1532 static const true_false_string tfs_file_attribute_encrypted = {
1533         "This is an ENCRYPTED file",
1534         "This is NOT an encrypted file"
1535 };
1536
1537 /*
1538  * In some places in the CIFS_TR_1p00.pdf, from SNIA, file attributes are 
1539  * listed as USHORT, and seem to be in packets in the wild, while in other
1540  * places they are listed as ULONG, and also seem to be.
1541  *
1542  * So, I (Richard Sharpe), added a parameter to allow us to specify how many
1543  * bytes to consume.
1544  */
1545
1546 static int
1547 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1548                         int bytes)
1549 {
1550         guint16 mask;
1551         proto_item *item = NULL;
1552         proto_tree *tree = NULL;
1553
1554         if (bytes != 2 && bytes != 4) {
1555
1556                 fprintf(stderr, "Incorrect number of bytes passed to dissect_file_attributes.\nMust be 2 or 4, was %d\n", bytes);
1557                 exit(1);
1558
1559         }
1560
1561         /*
1562          * The actual bits of interest appear to only be a USHORT
1563          */
1564         /* FIXME if this ever changes! */
1565         mask = tvb_get_letohs(tvb, offset);
1566
1567         if(parent_tree){
1568                 item = proto_tree_add_text(parent_tree, tvb, offset, bytes,
1569                         "File Attributes: 0x%08x", mask);
1570                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1571         }
1572         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted, 
1573                                tvb, offset, bytes, mask);       
1574         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed, 
1575                                tvb, offset, bytes, mask);
1576         proto_tree_add_boolean(tree, hf_smb_file_attr_offline, 
1577                                tvb, offset, bytes, mask);
1578         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed, 
1579                                tvb, offset, bytes, mask);
1580         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse, 
1581                                tvb, offset, bytes, mask);
1582         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse, 
1583                                tvb, offset, bytes, mask);
1584         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary, 
1585                                tvb, offset, bytes, mask);
1586         proto_tree_add_boolean(tree, hf_smb_file_attr_normal, 
1587                                tvb, offset, bytes, mask);
1588         proto_tree_add_boolean(tree, hf_smb_file_attr_device, 
1589                                tvb, offset, bytes, mask);
1590         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1591                 tvb, offset, bytes, mask);
1592         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1593                 tvb, offset, bytes, mask);
1594         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1595                 tvb, offset, bytes, mask);
1596         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1597                 tvb, offset, bytes, mask);
1598         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1599                 tvb, offset, bytes, mask);
1600         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1601                 tvb, offset, bytes, mask);
1602
1603         offset += bytes;
1604
1605         return offset;
1606 }
1607
1608 /* 3.11 */
1609 static int
1610 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1611 {
1612         guint32 mask;
1613         proto_item *item = NULL;
1614         proto_tree *tree = NULL;
1615
1616         mask = tvb_get_letohl(tvb, offset);
1617
1618         if(parent_tree){
1619                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1620                         "File Attributes: 0x%08x", mask);
1621                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1622         }
1623
1624         /*
1625          * XXX - Network Monitor disagrees on some of the
1626          * bits, e.g. the bits above temporary are "atomic write"
1627          * and "transaction write", and it says nothing about the
1628          * bits above that.
1629          *
1630          * Does the Win32 API documentation, or the NT Native API book,
1631          * suggest anything?
1632          */
1633         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1634                 tvb, offset, 4, mask);
1635         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1636                 tvb, offset, 4, mask);
1637         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1638                 tvb, offset, 4, mask);
1639         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1640                 tvb, offset, 4, mask);
1641         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1642                 tvb, offset, 4, mask);
1643         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1644                 tvb, offset, 4, mask);
1645         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1646                 tvb, offset, 4, mask);
1647         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1648                 tvb, offset, 4, mask);
1649         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1650                 tvb, offset, 4, mask);
1651         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1652                 tvb, offset, 4, mask);
1653         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1654                 tvb, offset, 4, mask);
1655         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1656                 tvb, offset, 4, mask);
1657         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1658                 tvb, offset, 4, mask);
1659         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1660                 tvb, offset, 4, mask);
1661         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1662                 tvb, offset, 4, mask);
1663
1664         offset += 4;
1665
1666         return offset;
1667 }
1668
1669 static int
1670 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1671 {
1672         guint8 mask;
1673         proto_item *item = NULL;
1674         proto_tree *tree = NULL;
1675
1676         mask = tvb_get_guint8(tvb, offset);
1677
1678         if(parent_tree){
1679                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1680                         "File Attributes: 0x%02x", mask);
1681                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1682         }
1683         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1684                 tvb, offset, 1, mask);
1685         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1686                 tvb, offset, 1, mask);
1687         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1688                 tvb, offset, 1, mask);
1689         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1690                 tvb, offset, 1, mask);
1691         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1692                 tvb, offset, 1, mask);
1693         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1694                 tvb, offset, 1, mask);
1695
1696         offset += 1;
1697
1698         return offset;
1699 }
1700
1701 static const true_false_string tfs_search_attribute_read_only = {
1702         "Include READ ONLY files in search results",
1703         "Do NOT include read only files in search results",
1704 };
1705 static const true_false_string tfs_search_attribute_hidden = {
1706         "Include HIDDEN files in search results",
1707         "Do NOT include hidden files in search results"
1708 };
1709 static const true_false_string tfs_search_attribute_system = {
1710         "Include SYSTEM files in search results",
1711         "Do NOT include system files in search results"
1712 };
1713 static const true_false_string tfs_search_attribute_volume = {
1714         "Include VOLUME IDs in search results",
1715         "Do NOT include volume IDs in search results"
1716 };
1717 static const true_false_string tfs_search_attribute_directory = {
1718         "Include DIRECTORIES in search results",
1719         "Do NOT include directories in search results"
1720 };
1721 static const true_false_string tfs_search_attribute_archive = {
1722         "Include ARCHIVE files in search results",
1723         "Do NOT include archive files in search results"
1724 };
1725
1726 static int
1727 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1728 {
1729         guint16 mask;
1730         proto_item *item = NULL;
1731         proto_tree *tree = NULL;
1732
1733         mask = tvb_get_letohs(tvb, offset);
1734
1735         if(parent_tree){
1736                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1737                         "Search Attributes: 0x%04x", mask);
1738                 tree = proto_item_add_subtree(item, ett_smb_search);
1739         }
1740
1741         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1742                 tvb, offset, 2, mask);
1743         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1744                 tvb, offset, 2, mask);
1745         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1746                 tvb, offset, 2, mask);
1747         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1748                 tvb, offset, 2, mask);
1749         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1750                 tvb, offset, 2, mask);
1751         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1752                 tvb, offset, 2, mask);
1753
1754         offset += 2;
1755         return offset;
1756 }
1757
1758 #if 0
1759 /*
1760  * XXX - this isn't used.
1761  * Is this used for anything?  NT Create AndX doesn't use it.
1762  * Is there some 16-bit attribute field with more bits than Read Only,
1763  * Hidden, System, Volume ID, Directory, and Archive?
1764  */
1765 static int
1766 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1767 {
1768         guint32 mask;
1769         proto_item *item = NULL;
1770         proto_tree *tree = NULL;
1771
1772         mask = tvb_get_letohl(tvb, offset);
1773
1774         if(parent_tree){
1775                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1776                         "File Attributes: 0x%08x", mask);
1777                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1778         }
1779         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1780                 tvb, offset, 2, mask);
1781         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1782                 tvb, offset, 2, mask);
1783         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1784                 tvb, offset, 2, mask);
1785         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1786                 tvb, offset, 2, mask);
1787         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1788                 tvb, offset, 2, mask);
1789         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1790                 tvb, offset, 2, mask);
1791         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1792                 tvb, offset, 2, mask);
1793         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1794                 tvb, offset, 2, mask);
1795         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1796                 tvb, offset, 2, mask);
1797         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1798                 tvb, offset, 2, mask);
1799         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1800                 tvb, offset, 2, mask);
1801         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1802                 tvb, offset, 2, mask);
1803         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1804                 tvb, offset, 2, mask);
1805         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1806                 tvb, offset, 2, mask);
1807         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1808                 tvb, offset, 2, mask);
1809
1810         offset += 2;
1811
1812         return offset;
1813 }
1814 #endif
1815
1816
1817 #define SERVER_CAP_RAW_MODE            0x00000001
1818 #define SERVER_CAP_MPX_MODE            0x00000002
1819 #define SERVER_CAP_UNICODE             0x00000004
1820 #define SERVER_CAP_LARGE_FILES         0x00000008
1821 #define SERVER_CAP_NT_SMBS             0x00000010
1822 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1823 #define SERVER_CAP_STATUS32            0x00000040
1824 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1825 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1826 #define SERVER_CAP_NT_FIND             0x00000200
1827 #define SERVER_CAP_DFS                 0x00001000
1828 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1829 #define SERVER_CAP_LARGE_READX         0x00004000
1830 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1831 #define SERVER_CAP_UNIX                0x00800000
1832 #define SERVER_CAP_RESERVED            0x02000000
1833 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1834 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1835 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1836 static const true_false_string tfs_server_cap_raw_mode = {
1837         "Read Raw and Write Raw are supported",
1838         "Read Raw and Write Raw are not supported"
1839 };
1840 static const true_false_string tfs_server_cap_mpx_mode = {
1841         "Read Mpx and Write Mpx are supported",
1842         "Read Mpx and Write Mpx are not supported"
1843 };
1844 static const true_false_string tfs_server_cap_unicode = {
1845         "Unicode strings are supported",
1846         "Unicode strings are not supported"
1847 };
1848 static const true_false_string tfs_server_cap_large_files = {
1849         "Large files are supported",
1850         "Large files are not supported",
1851 };
1852 static const true_false_string tfs_server_cap_nt_smbs = {
1853         "NT SMBs are supported",
1854         "NT SMBs are not supported"
1855 };
1856 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1857         "RPC remote APIs are supported",
1858         "RPC remote APIs are not supported"
1859 };
1860 static const true_false_string tfs_server_cap_nt_status = {
1861         "NT status codes are supported",
1862         "NT status codes are not supported"
1863 };
1864 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1865         "Level 2 oplocks are supported",
1866         "Level 2 oplocks are not supported"
1867 };
1868 static const true_false_string tfs_server_cap_lock_and_read = {
1869         "Lock and Read is supported",
1870         "Lock and Read is not supported"
1871 };
1872 static const true_false_string tfs_server_cap_nt_find = {
1873         "NT Find is supported",
1874         "NT Find is not supported"
1875 };
1876 static const true_false_string tfs_server_cap_dfs = {
1877         "Dfs is supported",
1878         "Dfs is not supported"
1879 };
1880 static const true_false_string tfs_server_cap_infolevel_passthru = {
1881         "NT information level request passthrough is supported",
1882         "NT information level request passthrough is not supported"
1883 };
1884 static const true_false_string tfs_server_cap_large_readx = {
1885         "Large Read andX is supported",
1886         "Large Read andX is not supported"
1887 };
1888 static const true_false_string tfs_server_cap_large_writex = {
1889         "Large Write andX is supported",
1890         "Large Write andX is not supported"
1891 };
1892 static const true_false_string tfs_server_cap_unix = {
1893         "UNIX extensions are supported",
1894         "UNIX extensions are not supported"
1895 };
1896 static const true_false_string tfs_server_cap_reserved = {
1897         "Reserved",
1898         "Reserved"
1899 };
1900 static const true_false_string tfs_server_cap_bulk_transfer = {
1901         "Bulk Read and Bulk Write are supported",
1902         "Bulk Read and Bulk Write are not supported"
1903 };
1904 static const true_false_string tfs_server_cap_compressed_data = {
1905         "Compressed data transfer is supported",
1906         "Compressed data transfer is not supported"
1907 };
1908 static const true_false_string tfs_server_cap_extended_security = {
1909         "Extended security exchanges are supported",
1910         "Extended security exchanges are not supported"
1911 };
1912 static int
1913 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1914 {
1915         guint32 mask;
1916         proto_item *item = NULL;
1917         proto_tree *tree = NULL;
1918
1919         mask = tvb_get_letohl(tvb, offset);
1920
1921         if(parent_tree){
1922                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1923                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1924         }
1925
1926         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1927                 tvb, offset, 4, mask);
1928         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1929                 tvb, offset, 4, mask);
1930         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1931                 tvb, offset, 4, mask);
1932         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1933                 tvb, offset, 4, mask);
1934         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1935                 tvb, offset, 4, mask);
1936         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1937                 tvb, offset, 4, mask);
1938         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1939                 tvb, offset, 4, mask);
1940         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1941                 tvb, offset, 4, mask);
1942         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1943                 tvb, offset, 4, mask);
1944         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1945                 tvb, offset, 4, mask);
1946         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1947                 tvb, offset, 4, mask);
1948         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1949                 tvb, offset, 4, mask);
1950         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1951                 tvb, offset, 4, mask);
1952         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1953                 tvb, offset, 4, mask);
1954         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1955                 tvb, offset, 4, mask);
1956         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1957                 tvb, offset, 4, mask);
1958         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1959                 tvb, offset, 4, mask);
1960         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1961                 tvb, offset, 4, mask);
1962         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1963                 tvb, offset, 4, mask);
1964
1965         return mask;
1966 }
1967
1968 #define RAWMODE_READ   0x01
1969 #define RAWMODE_WRITE  0x02
1970 static const true_false_string tfs_rm_read = {
1971         "Read Raw is supported",
1972         "Read Raw is not supported"
1973 };
1974 static const true_false_string tfs_rm_write = {
1975         "Write Raw is supported",
1976         "Write Raw is not supported"
1977 };
1978
1979 static int
1980 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1981 {
1982         guint16 mask;
1983         proto_item *item = NULL;
1984         proto_tree *tree = NULL;
1985
1986         mask = tvb_get_letohs(tvb, offset);
1987
1988         if(parent_tree){
1989                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1990                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1991         }
1992
1993         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
1994         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
1995
1996         offset += 2;
1997
1998         return offset;
1999 }
2000
2001 #define SECURITY_MODE_MODE             0x01
2002 #define SECURITY_MODE_PASSWORD         0x02
2003 #define SECURITY_MODE_SIGNATURES       0x04
2004 #define SECURITY_MODE_SIG_REQUIRED     0x08
2005 static const true_false_string tfs_sm_mode = {
2006         "USER security mode",
2007         "SHARE security mode"
2008 };
2009 static const true_false_string tfs_sm_password = {
2010         "ENCRYPTED password. Use challenge/response",
2011         "PLAINTEXT password"
2012 };
2013 static const true_false_string tfs_sm_signatures = {
2014         "Security signatures ENABLED",
2015         "Security signatures NOT enabled"
2016 };
2017 static const true_false_string tfs_sm_sig_required = {
2018         "Security signatures REQUIRED",
2019         "Security signatures NOT required"
2020 };
2021
2022 static int
2023 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
2024 {
2025         guint16 mask = 0;
2026         proto_item *item = NULL;
2027         proto_tree *tree = NULL;
2028
2029         switch(wc){
2030         case 13:
2031                 mask = tvb_get_letohs(tvb, offset);
2032                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2033                                 "Security Mode: 0x%04x", mask);
2034                 tree = proto_item_add_subtree(item, ett_smb_mode);
2035                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
2036                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
2037                 offset += 2;
2038                 break;
2039
2040         case 17:
2041                 mask = tvb_get_guint8(tvb, offset);
2042                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
2043                                 "Security Mode: 0x%02x", mask);
2044                 tree = proto_item_add_subtree(item, ett_smb_mode);
2045                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2046                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2047                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2048                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2049                 offset += 1;
2050                 break;
2051         }
2052
2053         return offset;
2054 }
2055
2056 static int
2057 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2058 {
2059         proto_item *it = NULL;
2060         proto_tree *tr = NULL;
2061         guint16 bc;
2062         guint8 wc;
2063
2064         WORD_COUNT;
2065
2066         BYTE_COUNT;
2067
2068         if(tree){
2069                 it = proto_tree_add_text(tree, tvb, offset, bc,
2070                                 "Requested Dialects");
2071                 tr = proto_item_add_subtree(it, ett_smb_dialects);
2072         }
2073
2074         while(bc){
2075                 int len;
2076                 const guint8 *str;
2077                 proto_item *dit = NULL;
2078                 proto_tree *dtr = NULL;
2079
2080                 /* XXX - what if this runs past bc? */
2081                 len = tvb_strsize(tvb, offset+1);
2082                 str = tvb_get_ptr(tvb, offset+1, len);
2083
2084                 if(tr){
2085                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2086                                         "Dialect: %s", str);
2087                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2088                 }
2089
2090                 /* Buffer Format */
2091                 CHECK_BYTE_COUNT(1);
2092                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2093                         TRUE);
2094                 COUNT_BYTES(1);
2095
2096                 /*Dialect Name */
2097                 CHECK_BYTE_COUNT(len);
2098                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2099                         len, str);
2100                 COUNT_BYTES(len);
2101         }
2102
2103         END_OF_SMB
2104
2105         return offset;
2106 }
2107
2108 static int
2109 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2110 {
2111         smb_info_t *si = pinfo->private_data;
2112         guint8 wc;
2113         guint16 dialect;
2114         const char *dn;
2115         int dn_len;
2116         guint16 bc;
2117         guint16 ekl=0;
2118         guint32 caps=0;
2119         gint16 tz;
2120
2121         WORD_COUNT;
2122
2123         /* Dialect Index */
2124         dialect = tvb_get_letohs(tvb, offset);
2125         switch(wc){
2126         case 1:
2127                 if(dialect==0xffff){
2128                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2129                                 tvb, offset, 2, dialect,
2130                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2131                 } else {
2132                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2133                                 tvb, offset, 2, dialect);
2134                 }
2135                 break;
2136         case 13:
2137                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2138                         tvb, offset, 2, dialect,
2139                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2140                 break;
2141         case 17:
2142                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2143                         tvb, offset, 2, dialect,
2144                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2145                 break;
2146         default:
2147                 proto_tree_add_text(tree, tvb, offset, wc*2,
2148                         "Words for unknown response format");
2149                 offset += wc*2;
2150                 goto bytecount;
2151         }
2152         offset += 2;
2153
2154         switch(wc){
2155         case 13:
2156                 /* Security Mode */
2157                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2158
2159                 /* Maximum Transmit Buffer Size */
2160                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2161                         tvb, offset, 2, TRUE);
2162                 offset += 2;
2163
2164                 /* Maximum Multiplex Count */
2165                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2166                         tvb, offset, 2, TRUE);
2167                 offset += 2;
2168
2169                 /* Maximum Vcs Number */
2170                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2171                         tvb, offset, 2, TRUE);
2172                 offset += 2;
2173
2174                 /* raw mode */
2175                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2176
2177                 /* session key */
2178                 proto_tree_add_item(tree, hf_smb_session_key,
2179                         tvb, offset, 4, TRUE);
2180                 offset += 4;
2181
2182                 /* current time and date at server */
2183                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2184                     TRUE);
2185
2186                 /* time zone */
2187                 tz = tvb_get_letohs(tvb, offset);
2188                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2189                 offset += 2;
2190
2191                 /* encryption key length */
2192                 ekl = tvb_get_letohs(tvb, offset);
2193                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2194                 offset += 2;
2195
2196                 /* 2 reserved bytes */
2197                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2198                 offset += 2;
2199
2200                 break;
2201
2202         case 17:
2203                 /* Security Mode */
2204                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2205
2206                 /* Maximum Multiplex Count */
2207                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2208                         tvb, offset, 2, TRUE);
2209                 offset += 2;
2210
2211                 /* Maximum Vcs Number */
2212                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2213                         tvb, offset, 2, TRUE);
2214                 offset += 2;
2215
2216                 /* Maximum Transmit Buffer Size */
2217                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2218                         tvb, offset, 4, TRUE);
2219                 offset += 4;
2220
2221                 /* maximum raw buffer size */
2222                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2223                         tvb, offset, 4, TRUE);
2224                 offset += 4;
2225
2226                 /* session key */
2227                 proto_tree_add_item(tree, hf_smb_session_key,
2228                         tvb, offset, 4, TRUE);
2229                 offset += 4;
2230
2231                 /* server capabilities */
2232                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2233                 offset += 4;
2234
2235                 /* system time */
2236                 offset = dissect_smb_64bit_time(tvb, tree, offset,
2237                                 hf_smb_system_time);
2238
2239                 /* time zone */
2240                 tz = tvb_get_letohs(tvb, offset);
2241                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2242                         tvb, offset, 2, tz,
2243                         "Server Time Zone: %d min from UTC", tz);
2244                 offset += 2;
2245
2246                 /* encryption key length */
2247                 ekl = tvb_get_guint8(tvb, offset);
2248                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2249                         tvb, offset, 1, ekl);
2250                 offset += 1;
2251
2252                 break;
2253         }
2254
2255         BYTE_COUNT;
2256
2257         switch(wc){
2258         case 13:
2259                 /* challenge/response encryption key */
2260                 if(ekl){
2261                         CHECK_BYTE_COUNT(ekl);
2262                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2263                         COUNT_BYTES(ekl);
2264                 }
2265
2266                 /*
2267                  * Primary domain.
2268                  *
2269                  * XXX - not present if negotiated dialect isn't
2270                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2271                  * have to see the request, or assume what dialect strings
2272                  * were sent, to determine that.
2273                  *
2274                  * Is this something other than a primary domain if the
2275                  * negotiated dialect is Windows for Workgroups 3.1a?
2276                  * It appears to be 8 bytes of binary data in at least
2277                  * one capture - is that an encryption key or something
2278                  * such as that?
2279                  */
2280                 dn = get_unicode_or_ascii_string(tvb, &offset,
2281                         si->unicode, &dn_len, FALSE, FALSE, &bc);
2282                 if (dn == NULL)
2283                         goto endofcommand;
2284                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2285                         offset, dn_len,dn);
2286                 COUNT_BYTES(dn_len);
2287                 break;
2288
2289         case 17:
2290                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2291                         /* challenge/response encryption key */
2292                         /* XXX - is this aligned on an even boundary? */
2293                         if(ekl){
2294                                 CHECK_BYTE_COUNT(ekl);
2295                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2296                                         tvb, offset, ekl, TRUE);
2297                                 COUNT_BYTES(ekl);
2298                         }
2299
2300                         /* domain */
2301                         /* this string is special, unicode is flagged in caps */
2302                         /* This string is NOT padded to be 16bit aligned.
2303                            (seen in actual capture)
2304                            XXX - I've seen a capture where it appears to be
2305                            so aligned, but I've also seen captures where
2306                            it is.  The captures where it appeared to be
2307                            aligned may have been from buggy servers. */
2308                         /* However, don't get rid of existing setting */
2309                         si->unicode = (caps&SERVER_CAP_UNICODE) ||
2310                           si->unicode;
2311
2312                         dn = get_unicode_or_ascii_string(tvb,
2313                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2314                                 &bc);
2315                         if (dn == NULL)
2316                                 goto endofcommand;
2317                         proto_tree_add_string(tree, hf_smb_primary_domain,
2318                                 tvb, offset, dn_len, dn);
2319                         COUNT_BYTES(dn_len);
2320
2321                         /* server name, seen in w2k pro capture */
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_server,
2328                                 tvb, offset, dn_len, dn);
2329                         COUNT_BYTES(dn_len);
2330
2331                 } else {
2332                         proto_item *blob_item;
2333
2334                         /* guid */
2335                         /* XXX - show it in the standard Microsoft format
2336                            for GUIDs? */
2337                         CHECK_BYTE_COUNT(16);
2338                         proto_tree_add_item(tree, hf_smb_server_guid,
2339                                 tvb, offset, 16, TRUE);
2340                         COUNT_BYTES(16);
2341
2342                         blob_item = proto_tree_add_item(
2343                                 tree, hf_smb_security_blob,
2344                                 tvb, offset, bc, TRUE);
2345
2346                         /* security blob */
2347                         /* 
2348                          * If Extended security and BCC == 16, then raw 
2349                          * NTLMSSP is in use. We need to save this info
2350                          */
2351  
2352                         if(bc){
2353                                 tvbuff_t *gssapi_tvb;
2354                                 proto_tree *gssapi_tree;
2355
2356                                 gssapi_tree = proto_item_add_subtree(
2357                                         blob_item, ett_smb_secblob);
2358
2359                                 gssapi_tvb = tvb_new_subset(
2360                                         tvb, offset, bc, bc);
2361
2362                                 call_dissector(
2363                                         gssapi_handle, gssapi_tvb, pinfo,
2364                                         gssapi_tree);
2365
2366                                 if (si->ct)
2367                                   si->ct->raw_ntlmssp = 0;
2368
2369                                 COUNT_BYTES(bc);
2370                         }
2371                         else { 
2372
2373                           /*
2374                            * There is no blob. We just have to make sure
2375                            * that subsequent routines know to call the 
2376                            * right things ...
2377                            */
2378
2379                           if (si->ct)
2380                             si->ct->raw_ntlmssp = 1;
2381
2382                         }
2383                 }
2384                 break;
2385         }
2386
2387         END_OF_SMB
2388
2389         return offset;
2390 }
2391
2392
2393 static int
2394 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2395 {
2396         smb_info_t *si = pinfo->private_data;
2397         int dn_len;
2398         const char *dn;
2399         guint8 wc;
2400         guint16 bc;
2401
2402         WORD_COUNT;
2403
2404         BYTE_COUNT;
2405
2406         /* buffer format */
2407         CHECK_BYTE_COUNT(1);
2408         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2409         COUNT_BYTES(1);
2410
2411         /* dir name */
2412         dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
2413                 FALSE, FALSE, &bc);
2414         if (dn == NULL)
2415                 goto endofcommand;
2416         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2417                 dn);
2418         COUNT_BYTES(dn_len);
2419
2420         if (check_col(pinfo->cinfo, COL_INFO)) {
2421                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s", dn);
2422         }
2423
2424         END_OF_SMB
2425
2426         return offset;
2427 }
2428
2429 static int
2430 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2431 {
2432         guint8 wc;
2433         guint16 bc;
2434
2435         WORD_COUNT;
2436
2437         BYTE_COUNT;
2438
2439         END_OF_SMB
2440
2441         return offset;
2442 }
2443
2444 static int
2445 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2446 {
2447         guint16 ec, bc;
2448         guint8 wc;
2449
2450         WORD_COUNT;
2451
2452         /* echo count */
2453         ec = tvb_get_letohs(tvb, offset);
2454         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2455         offset += 2;
2456
2457         BYTE_COUNT;
2458
2459         if (bc != 0) {
2460                 /* echo data */
2461                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2462                 COUNT_BYTES(bc);
2463         }
2464
2465         END_OF_SMB
2466
2467         return offset;
2468 }
2469
2470 static int
2471 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2472 {
2473         guint16 bc;
2474         guint8 wc;
2475
2476         WORD_COUNT;
2477
2478         /* echo sequence number */
2479         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2480         offset += 2;
2481
2482         BYTE_COUNT;
2483
2484         if (bc != 0) {
2485                 /* echo data */
2486                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2487                 COUNT_BYTES(bc);
2488         }
2489
2490         END_OF_SMB
2491
2492         return offset;
2493 }
2494
2495 static int
2496 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2497 {
2498         smb_info_t *si = pinfo->private_data;
2499         int an_len, pwlen;
2500         const char *an;
2501         guint8 wc;
2502         guint16 bc;
2503
2504         WORD_COUNT;
2505
2506         BYTE_COUNT;
2507
2508         /* buffer format */
2509         CHECK_BYTE_COUNT(1);
2510         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2511         COUNT_BYTES(1);
2512
2513         /* Path */
2514         an = get_unicode_or_ascii_string(tvb, &offset,
2515                 si->unicode, &an_len, FALSE, FALSE, &bc);
2516         if (an == NULL)
2517                 goto endofcommand;
2518         proto_tree_add_string(tree, hf_smb_path, tvb,
2519                 offset, an_len, an);
2520         COUNT_BYTES(an_len);
2521
2522         if (check_col(pinfo->cinfo, COL_INFO)) {
2523                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
2524         }
2525
2526         /* buffer format */
2527         CHECK_BYTE_COUNT(1);
2528         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2529         COUNT_BYTES(1);
2530
2531         /* password, ANSI */
2532         /* XXX - what if this runs past bc? */
2533         pwlen = tvb_strsize(tvb, offset);
2534         CHECK_BYTE_COUNT(pwlen);
2535         proto_tree_add_item(tree, hf_smb_password,
2536                 tvb, offset, pwlen, TRUE);
2537         COUNT_BYTES(pwlen);
2538
2539         /* buffer format */
2540         CHECK_BYTE_COUNT(1);
2541         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2542         COUNT_BYTES(1);
2543
2544         /* Service */
2545         an = get_unicode_or_ascii_string(tvb, &offset,
2546                 si->unicode, &an_len, FALSE, FALSE, &bc);
2547         if (an == NULL)
2548                 goto endofcommand;
2549         proto_tree_add_string(tree, hf_smb_service, tvb,
2550                 offset, an_len, an);
2551         COUNT_BYTES(an_len);
2552
2553         END_OF_SMB
2554
2555         return offset;
2556 }
2557
2558 static int
2559 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2560 {
2561         guint8 wc;
2562         guint16 bc;
2563
2564         WORD_COUNT;
2565
2566         /* Maximum Buffer Size */
2567         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2568         offset += 2;
2569
2570         /* tid */
2571         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2572         offset += 2;
2573
2574         BYTE_COUNT;
2575
2576         END_OF_SMB
2577
2578         return offset;
2579 }
2580
2581
2582 static const true_false_string tfs_of_create = {
2583         "Create file if it does not exist",
2584         "Fail if file does not exist"
2585 };
2586 static const value_string of_open[] = {
2587         { 0,            "Fail if file exists"},
2588         { 1,            "Open file if it exists"},
2589         { 2,            "Truncate file if it exists"},
2590         {0, NULL}
2591 };
2592 static int
2593 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2594 {
2595         guint16 mask;
2596         proto_item *item = NULL;
2597         proto_tree *tree = NULL;
2598
2599         mask = tvb_get_letohs(tvb, offset);
2600
2601         if(parent_tree){
2602                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2603                         "Open Function: 0x%04x", mask);
2604                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2605         }
2606
2607         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2608                 tvb, offset, 2, mask);
2609         proto_tree_add_uint(tree, hf_smb_open_function_open,
2610                 tvb, offset, 2, mask);
2611
2612         offset += 2;
2613
2614         return offset;
2615 }
2616
2617
2618 static const true_false_string tfs_mf_file = {
2619         "Target must be a file",
2620         "Target needn't be a file"
2621 };
2622 static const true_false_string tfs_mf_dir = {
2623         "Target must be a directory",
2624         "Target needn't be a directory"
2625 };
2626 static const true_false_string tfs_mf_verify = {
2627         "MUST verify all writes",
2628         "Don't have to verify writes"
2629 };
2630 static int
2631 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2632 {
2633         guint16 mask;
2634         proto_item *item = NULL;
2635         proto_tree *tree = NULL;
2636
2637         mask = tvb_get_letohs(tvb, offset);
2638
2639         if(parent_tree){
2640                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2641                         "Flags: 0x%04x", mask);
2642                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2643         }
2644
2645         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2646                 tvb, offset, 2, mask);
2647         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2648                 tvb, offset, 2, mask);
2649         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2650                 tvb, offset, 2, mask);
2651
2652         offset += 2;
2653
2654         return offset;
2655 }
2656
2657 static const true_false_string tfs_cf_mode = {
2658         "ASCII",
2659         "Binary"
2660 };
2661 static const true_false_string tfs_cf_tree_copy = {
2662         "Copy is a tree copy",
2663         "Copy is a file copy"
2664 };
2665 static const true_false_string tfs_cf_ea_action = {
2666         "Fail copy",
2667         "Discard EAs"
2668 };
2669 static int
2670 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2671 {
2672         guint16 mask;
2673         proto_item *item = NULL;
2674         proto_tree *tree = NULL;
2675
2676         mask = tvb_get_letohs(tvb, offset);
2677
2678         if(parent_tree){
2679                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2680                         "Flags: 0x%04x", mask);
2681                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2682         }
2683
2684         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
2685                 tvb, offset, 2, mask);
2686         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2687                 tvb, offset, 2, mask);
2688         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2689                 tvb, offset, 2, mask);
2690         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2691                 tvb, offset, 2, mask);
2692         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2693                 tvb, offset, 2, mask);
2694         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2695                 tvb, offset, 2, mask);
2696         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2697                 tvb, offset, 2, mask);
2698
2699         offset += 2;
2700
2701         return offset;
2702 }
2703
2704 static int
2705 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2706 {
2707         smb_info_t *si = pinfo->private_data;
2708         int fn_len;
2709         guint16 tid;
2710         guint16 bc;
2711         guint8 wc;
2712         const char *fn;
2713
2714         WORD_COUNT;
2715
2716         /* tid */
2717         tid = tvb_get_letohs(tvb, offset);
2718         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2719                 "TID (target): 0x%04x", tid);
2720         offset += 2;
2721
2722         /* open function */
2723         offset = dissect_open_function(tvb, tree, offset);
2724
2725         /* move flags */
2726         offset = dissect_move_flags(tvb, tree, offset);
2727
2728         BYTE_COUNT;
2729
2730         /* buffer format */
2731         CHECK_BYTE_COUNT(1);
2732         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2733         COUNT_BYTES(1);
2734
2735         /* file name */
2736         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2737                 FALSE, FALSE, &bc);
2738         if (fn == NULL)
2739                 goto endofcommand;
2740         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2741                 fn_len, fn, "Old File Name: %s", fn);
2742         COUNT_BYTES(fn_len);
2743
2744         if (check_col(pinfo->cinfo, COL_INFO)) {
2745                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2746         }
2747
2748         /* buffer format */
2749         CHECK_BYTE_COUNT(1);
2750         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2751         COUNT_BYTES(1);
2752
2753         /* file name */
2754         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2755                 FALSE, FALSE, &bc);
2756         if (fn == NULL)
2757                 goto endofcommand;
2758         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2759                 fn_len, fn, "New File Name: %s", fn);
2760         COUNT_BYTES(fn_len);
2761
2762         if (check_col(pinfo->cinfo, COL_INFO)) {
2763                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2764         }
2765
2766         END_OF_SMB
2767
2768         return offset;
2769 }
2770
2771 static int
2772 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2773 {
2774         smb_info_t *si = pinfo->private_data;
2775         int fn_len;
2776         guint16 tid;
2777         guint16 bc;
2778         guint8 wc;
2779         const char *fn;
2780
2781         WORD_COUNT;
2782
2783         /* tid */
2784         tid = tvb_get_letohs(tvb, offset);
2785         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2786                 "TID (target): 0x%04x", tid);
2787         offset += 2;
2788
2789         /* open function */
2790         offset = dissect_open_function(tvb, tree, offset);
2791
2792         /* copy flags */
2793         offset = dissect_copy_flags(tvb, tree, offset);
2794
2795         BYTE_COUNT;
2796
2797         /* buffer format */
2798         CHECK_BYTE_COUNT(1);
2799         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2800         COUNT_BYTES(1);
2801
2802         /* file name */
2803         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2804                 FALSE, FALSE, &bc);
2805         if (fn == NULL)
2806                 goto endofcommand;
2807         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2808                 fn_len, fn, "Source File Name: %s", fn);
2809         COUNT_BYTES(fn_len);
2810
2811         if (check_col(pinfo->cinfo, COL_INFO)) {
2812                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s", fn);
2813         }
2814
2815         /* buffer format */
2816         CHECK_BYTE_COUNT(1);
2817         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2818         COUNT_BYTES(1);
2819
2820         /* file name */
2821         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2822                 FALSE, FALSE, &bc);
2823         if (fn == NULL)
2824                 goto endofcommand;
2825         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2826                 fn_len, fn, "Destination File Name: %s", fn);
2827         COUNT_BYTES(fn_len);
2828
2829         if (check_col(pinfo->cinfo, COL_INFO)) {
2830                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", fn);
2831         }
2832
2833         END_OF_SMB
2834
2835         return offset;
2836 }
2837
2838 static int
2839 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2840 {
2841         smb_info_t *si = pinfo->private_data;
2842         int fn_len;
2843         const char *fn;
2844         guint8 wc;
2845         guint16 bc;
2846
2847         WORD_COUNT;
2848
2849         /* # of files moved */
2850         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
2851         offset += 2;
2852
2853         BYTE_COUNT;
2854
2855         /* buffer format */
2856         CHECK_BYTE_COUNT(1);
2857         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2858         COUNT_BYTES(1);
2859
2860         /* file name */
2861         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2862                 FALSE, FALSE, &bc);
2863         if (fn == NULL)
2864                 goto endofcommand;
2865         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2866                 fn);
2867         COUNT_BYTES(fn_len);
2868
2869         END_OF_SMB
2870
2871         return offset;
2872 }
2873
2874 static int
2875 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2876 {
2877         smb_info_t *si = pinfo->private_data;
2878         int fn_len;
2879         const char *fn;
2880         guint8 wc;
2881         guint16 bc;
2882
2883         WORD_COUNT;
2884
2885         /* desired access */
2886         offset = dissect_access(tvb, tree, offset, "Desired");
2887
2888         /* Search Attributes */
2889         offset = dissect_search_attributes(tvb, tree, offset);
2890
2891         BYTE_COUNT;
2892
2893         /* buffer format */
2894         CHECK_BYTE_COUNT(1);
2895         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2896         COUNT_BYTES(1);
2897
2898         /* file name */
2899         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2900                 FALSE, FALSE, &bc);
2901         if (fn == NULL)
2902                 goto endofcommand;
2903         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2904                 fn);
2905         COUNT_BYTES(fn_len);
2906
2907         if (check_col(pinfo->cinfo, COL_INFO)) {
2908                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2909         }
2910
2911         END_OF_SMB
2912
2913         return offset;
2914 }
2915
2916 void
2917 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2918     int len, guint16 fid)
2919 {
2920         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2921         if (check_col(pinfo->cinfo, COL_INFO))
2922                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2923 }
2924
2925 static int
2926 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2927 {
2928         guint8 wc;
2929         guint16 bc;
2930         guint16 fid;
2931
2932         WORD_COUNT;
2933
2934         /* fid */
2935         fid = tvb_get_letohs(tvb, offset);
2936         add_fid(tvb, pinfo, tree, offset, 2, fid);
2937         offset += 2;
2938
2939         /* File Attributes */
2940         offset = dissect_file_attributes(tvb, tree, offset, 2);
2941
2942         /* last write time */
2943         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2944
2945         /* File Size */
2946         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2947         offset += 4;
2948
2949         /* granted access */
2950         offset = dissect_access(tvb, tree, offset, "Granted");
2951
2952         BYTE_COUNT;
2953
2954         END_OF_SMB
2955
2956         return offset;
2957 }
2958
2959 static int
2960 dissect_fid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2961 {
2962         guint8 wc;
2963         guint16 bc;
2964         guint16 fid;
2965
2966         WORD_COUNT;
2967
2968         /* fid */
2969         fid = tvb_get_letohs(tvb, offset);
2970         add_fid(tvb, pinfo, tree, offset, 2, fid);
2971         offset += 2;
2972
2973         BYTE_COUNT;
2974
2975         END_OF_SMB
2976
2977         return offset;
2978 }
2979
2980 static int
2981 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2982 {
2983         smb_info_t *si = pinfo->private_data;
2984         int fn_len;
2985         const char *fn;
2986         guint8 wc;
2987         guint16 bc;
2988
2989         WORD_COUNT;
2990
2991         /* file attributes */
2992         offset = dissect_file_attributes(tvb, tree, offset, 2);
2993
2994         /* creation time */
2995         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
2996
2997         BYTE_COUNT;
2998
2999         /* buffer format */
3000         CHECK_BYTE_COUNT(1);
3001         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3002         COUNT_BYTES(1);
3003
3004         /* File Name */
3005         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3006                 FALSE, FALSE, &bc);
3007         if (fn == NULL)
3008                 goto endofcommand;
3009         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3010                 fn);
3011         COUNT_BYTES(fn_len);
3012
3013         if (check_col(pinfo->cinfo, COL_INFO)) {
3014                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3015         }
3016
3017         END_OF_SMB
3018
3019         return offset;
3020 }
3021
3022 static int
3023 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3024 {
3025         guint8 wc;
3026         guint16 bc, fid;
3027
3028         WORD_COUNT;
3029
3030         /* fid */
3031         fid = tvb_get_letohs(tvb, offset);
3032         add_fid(tvb, pinfo, tree, offset, 2, fid);
3033         offset += 2;
3034
3035         /* last write time */
3036         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3037
3038         BYTE_COUNT;
3039
3040         END_OF_SMB
3041
3042         return offset;
3043 }
3044
3045 static int
3046 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3047 {
3048         smb_info_t *si = pinfo->private_data;
3049         int fn_len;
3050         const char *fn;
3051         guint8 wc;
3052         guint16 bc;
3053
3054         WORD_COUNT;
3055
3056         /* search attributes */
3057         offset = dissect_search_attributes(tvb, tree, offset);
3058
3059         BYTE_COUNT;
3060
3061         /* buffer format */
3062         CHECK_BYTE_COUNT(1);
3063         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3064         COUNT_BYTES(1);
3065
3066         /* file name */
3067         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3068                 FALSE, FALSE, &bc);
3069         if (fn == NULL)
3070                 goto endofcommand;
3071         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3072                 fn);
3073         COUNT_BYTES(fn_len);
3074
3075         if (check_col(pinfo->cinfo, COL_INFO)) {
3076                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3077         }
3078
3079         END_OF_SMB
3080
3081         return offset;
3082 }
3083
3084 static int
3085 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3086 {
3087         smb_info_t *si = pinfo->private_data;
3088         int fn_len;
3089         const char *fn;
3090         guint8 wc;
3091         guint16 bc;
3092
3093         WORD_COUNT;
3094
3095         /* search attributes */
3096         offset = dissect_search_attributes(tvb, tree, offset);
3097
3098         BYTE_COUNT;
3099
3100         /* buffer format */
3101         CHECK_BYTE_COUNT(1);
3102         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3103         COUNT_BYTES(1);
3104
3105         /* old file name */
3106         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3107                 FALSE, FALSE, &bc);
3108         if (fn == NULL)
3109                 goto endofcommand;
3110         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3111                 fn);
3112         COUNT_BYTES(fn_len);
3113
3114         if (check_col(pinfo->cinfo, COL_INFO)) {
3115                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3116         }
3117
3118         /* buffer format */
3119         CHECK_BYTE_COUNT(1);
3120         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3121         COUNT_BYTES(1);
3122
3123         /* file name */
3124         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3125                 FALSE, FALSE, &bc);
3126         if (fn == NULL)
3127                 goto endofcommand;
3128         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3129                 fn);
3130         COUNT_BYTES(fn_len);
3131
3132         if (check_col(pinfo->cinfo, COL_INFO)) {
3133                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3134         }
3135
3136         END_OF_SMB
3137
3138         return offset;
3139 }
3140
3141 static int
3142 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3143 {
3144         smb_info_t *si = pinfo->private_data;
3145         int fn_len;
3146         const char *fn;
3147         guint8 wc;
3148         guint16 bc;
3149
3150         WORD_COUNT;
3151
3152         /* search attributes */
3153         offset = dissect_search_attributes(tvb, tree, offset);
3154
3155         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3156         offset += 2;
3157
3158         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3159         offset += 4;
3160
3161         BYTE_COUNT;
3162
3163         /* buffer format */
3164         CHECK_BYTE_COUNT(1);
3165         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3166         COUNT_BYTES(1);
3167
3168         /* old file name */
3169         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3170                 FALSE, FALSE, &bc);
3171         if (fn == NULL)
3172                 goto endofcommand;
3173         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3174                 fn);
3175         COUNT_BYTES(fn_len);
3176
3177         if (check_col(pinfo->cinfo, COL_INFO)) {
3178                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3179         }
3180
3181         /* buffer format */
3182         CHECK_BYTE_COUNT(1);
3183         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3184         COUNT_BYTES(1);
3185
3186         /* file name */
3187         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3188                 FALSE, FALSE, &bc);
3189         if (fn == NULL)
3190                 goto endofcommand;
3191         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3192                 fn);
3193         COUNT_BYTES(fn_len);
3194
3195         if (check_col(pinfo->cinfo, COL_INFO)) {
3196                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3197         }
3198
3199         END_OF_SMB
3200
3201         return offset;
3202 }
3203
3204
3205 static int
3206 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3207 {
3208         smb_info_t *si = pinfo->private_data;
3209         guint16 bc;
3210         guint8 wc;
3211         const char *fn;
3212         int fn_len;
3213
3214         WORD_COUNT;
3215
3216         BYTE_COUNT;
3217
3218         /* Buffer Format */
3219         CHECK_BYTE_COUNT(1);
3220         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3221         COUNT_BYTES(1);
3222
3223         /* File Name */
3224         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3225                 FALSE, FALSE, &bc);
3226         if (fn == NULL)
3227                 goto endofcommand;
3228         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3229                 fn);
3230         COUNT_BYTES(fn_len);
3231
3232         if (check_col(pinfo->cinfo, COL_INFO)) {
3233                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3234         }
3235
3236         END_OF_SMB
3237
3238         return offset;
3239 }
3240
3241 static int
3242 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3243 {
3244         guint16 bc;
3245         guint8 wc;
3246
3247         WORD_COUNT;
3248
3249         /* File Attributes */
3250         offset = dissect_file_attributes(tvb, tree, offset, 2);
3251
3252         /* Last Write Time */
3253         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3254
3255         /* File Size */
3256         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3257         offset += 4;
3258
3259         /* 10 reserved bytes */
3260         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3261         offset += 10;
3262
3263         BYTE_COUNT;
3264
3265         END_OF_SMB
3266
3267         return offset;
3268 }
3269
3270 static int
3271 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3272 {
3273         smb_info_t *si = pinfo->private_data;
3274         int fn_len;
3275         const char *fn;
3276         guint8 wc;
3277         guint16 bc;
3278
3279         WORD_COUNT;
3280
3281         /* file attributes */
3282         offset = dissect_file_attributes(tvb, tree, offset, 2);
3283
3284         /* last write time */
3285         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3286
3287         /* 10 reserved bytes */
3288         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3289         offset += 10;
3290
3291         BYTE_COUNT;
3292
3293         /* buffer format */
3294         CHECK_BYTE_COUNT(1);
3295         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3296         COUNT_BYTES(1);
3297
3298         /* file name */
3299         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3300                 FALSE, FALSE, &bc);
3301         if (fn == NULL)
3302                 goto endofcommand;
3303         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3304                 fn);
3305         COUNT_BYTES(fn_len);
3306
3307         if (check_col(pinfo->cinfo, COL_INFO)) {
3308                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3309         }
3310
3311         END_OF_SMB
3312
3313         return offset;
3314 }
3315
3316 static int
3317 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3318 {
3319         guint8 wc;
3320         guint16 cnt=0, bc;
3321         guint32 ofs=0;
3322         smb_info_t *si;
3323         unsigned int fid;
3324
3325         WORD_COUNT;
3326
3327         /* fid */
3328         fid = tvb_get_letohs(tvb, offset);
3329         add_fid(tvb, pinfo, tree, offset, 2, fid);
3330         offset += 2;
3331         if (!pinfo->fd->flags.visited) {
3332                 /* remember the FID for the processing of the response */
3333                 si = (smb_info_t *)pinfo->private_data;
3334                 si->sip->extra_info=(void *)fid;
3335         }
3336
3337         /* read count */
3338         cnt = tvb_get_letohs(tvb, offset);
3339         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3340         offset += 2;
3341
3342         /* offset */
3343         ofs = tvb_get_letohl(tvb, offset);
3344         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3345         offset += 4;
3346
3347         if (check_col(pinfo->cinfo, COL_INFO))
3348                 col_append_fstr(pinfo->cinfo, COL_INFO,
3349                                 ", %u byte%s at offset %u", cnt,
3350                                 (cnt == 1) ? "" : "s", ofs);
3351
3352         /* remaining */
3353         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3354         offset += 2;
3355
3356         BYTE_COUNT;
3357
3358         END_OF_SMB
3359
3360         return offset;
3361 }
3362
3363 int
3364 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3365 {
3366         int tvblen;
3367
3368         if(bc>datalen){
3369                 /* We have some initial padding bytes. */
3370                 /* XXX - use the data offset here instead? */
3371                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3372                         TRUE);
3373                 offset += bc-datalen;
3374                 bc = datalen;
3375         }
3376         tvblen = tvb_length_remaining(tvb, offset);
3377         if(bc>tvblen){
3378                 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);
3379                 offset += tvblen;
3380         } else {
3381                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3382                 offset += bc;
3383         }
3384         return offset;
3385 }
3386
3387 static int
3388 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3389     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
3390 {
3391         int tvblen;
3392         tvbuff_t *dcerpc_tvb;
3393
3394         if(bc>datalen){
3395                 /* We have some initial padding bytes. */
3396                 /* XXX - use the data offset here instead? */
3397                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3398                         TRUE);
3399                 offset += bc-datalen;
3400                 bc = datalen;
3401         }
3402         tvblen = tvb_length_remaining(tvb, offset);
3403         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
3404         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
3405         if(bc>tvblen)
3406                 offset += tvblen;
3407         else
3408                 offset += bc;
3409         return offset;
3410 }
3411
3412 /*
3413  * transporting DCERPC over SMB seems to be implemented in various
3414  * ways. We might just assume it can be done by an almost random
3415  * mix of Trans/Read/Write calls
3416  *
3417  * if we suspect dcerpc, just send them all down to packet-smb-pipe.c
3418  * and let him sort them out
3419  */
3420 static int
3421 dissect_file_data_maybe_dcerpc(tvbuff_t *tvb, packet_info *pinfo,
3422     proto_tree *tree, proto_tree *top_tree, int offset, guint16 bc,
3423     guint16 datalen, guint32 ofs, guint16 fid)
3424 {
3425         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3426
3427         if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
3428                 /* dcerpc call */
3429                 return dissect_file_data_dcerpc(tvb, pinfo, tree,
3430                     top_tree, offset, bc, datalen, fid);
3431         } else {
3432                 /* ordinary file data */
3433                 return dissect_file_data(tvb, tree, offset, bc, datalen);
3434         }
3435 }
3436
3437 static int
3438 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3439 {
3440         guint16 cnt=0, bc;
3441         guint8 wc;
3442         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3443         int fid=0;
3444
3445         WORD_COUNT;
3446
3447         /* read count */
3448         cnt = tvb_get_letohs(tvb, offset);
3449         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3450         offset += 2;
3451
3452         /* 8 reserved bytes */
3453         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3454         offset += 8;
3455
3456         /* If we have seen the request, then print which FID this refers to */
3457         /* first check if we have seen the request */
3458         if(si->sip != NULL && si->sip->frame_req>0){
3459                 fid=(int)si->sip->extra_info;
3460                 add_fid(tvb, pinfo, tree, 0, 0, fid);
3461         }
3462
3463         BYTE_COUNT;
3464
3465         /* buffer format */
3466         CHECK_BYTE_COUNT(1);
3467         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3468         COUNT_BYTES(1);
3469
3470         /* data len */
3471         CHECK_BYTE_COUNT(2);
3472         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3473         COUNT_BYTES(2);
3474
3475         /* file data, might be DCERPC on a pipe */
3476         if(bc){
3477                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3478                     top_tree, offset, bc, bc, 0, fid);
3479                 bc = 0;
3480         }
3481
3482         END_OF_SMB
3483
3484         return offset;
3485 }
3486
3487 static int
3488 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3489 {
3490         guint16 cnt, bc;
3491         guint8 wc;
3492
3493         WORD_COUNT;
3494
3495         /* read count */
3496         cnt = tvb_get_letohs(tvb, offset);
3497         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3498         offset += 2;
3499
3500         /* 8 reserved bytes */
3501         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3502         offset += 8;
3503
3504         BYTE_COUNT;
3505
3506         /* buffer format */
3507         CHECK_BYTE_COUNT(1);
3508         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3509         COUNT_BYTES(1);
3510
3511         /* data len */
3512         CHECK_BYTE_COUNT(2);
3513         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3514         COUNT_BYTES(2);
3515
3516         END_OF_SMB
3517
3518         return offset;
3519 }
3520
3521
3522 static int
3523 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3524 {
3525         guint32 ofs=0;
3526         guint16 cnt=0, bc, fid=0;
3527         guint8 wc;
3528
3529         WORD_COUNT;
3530
3531         /* fid */
3532         fid = tvb_get_letohs(tvb, offset);
3533         add_fid(tvb, pinfo, tree, offset, 2, fid);
3534         offset += 2;
3535
3536         /* write count */
3537         cnt = tvb_get_letohs(tvb, offset);
3538         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3539         offset += 2;
3540
3541         /* offset */
3542         ofs = tvb_get_letohl(tvb, offset);
3543         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3544         offset += 4;
3545
3546         if (check_col(pinfo->cinfo, COL_INFO))
3547                 col_append_fstr(pinfo->cinfo, COL_INFO,
3548                                 ", %u byte%s at offset %u", cnt,
3549                                 (cnt == 1) ? "" : "s", ofs);
3550
3551         /* remaining */
3552         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3553         offset += 2;
3554
3555         BYTE_COUNT;
3556
3557         /* buffer format */
3558         CHECK_BYTE_COUNT(1);
3559         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3560         COUNT_BYTES(1);
3561
3562         /* data len */
3563         CHECK_BYTE_COUNT(2);
3564         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3565         COUNT_BYTES(2);
3566
3567         /* file data, might be DCERPC on a pipe */
3568         if (bc != 0) {
3569                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3570                     top_tree, offset, bc, bc, ofs, fid);
3571                 bc = 0;
3572         }
3573
3574         END_OF_SMB
3575
3576         return offset;
3577 }
3578
3579 static int
3580 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3581 {
3582         guint8 wc;
3583         guint16 bc, cnt;
3584
3585         WORD_COUNT;
3586
3587         /* write count */
3588         cnt = tvb_get_letohs(tvb, offset);
3589         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3590         offset += 2;
3591
3592         if (check_col(pinfo->cinfo, COL_INFO))
3593                 col_append_fstr(pinfo->cinfo, COL_INFO,
3594                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
3595
3596         BYTE_COUNT;
3597
3598         END_OF_SMB
3599
3600         return offset;
3601 }
3602
3603 static int
3604 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3605 {
3606         guint8 wc;
3607         guint16 bc, fid;
3608
3609         WORD_COUNT;
3610
3611         /* fid */
3612         fid = tvb_get_letohs(tvb, offset);
3613         add_fid(tvb, pinfo, tree, offset, 2, fid);
3614         offset += 2;
3615
3616         /* lock count */
3617         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3618         offset += 4;
3619
3620         /* offset */
3621         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3622         offset += 4;
3623
3624         BYTE_COUNT;
3625
3626         END_OF_SMB
3627
3628         return offset;
3629 }
3630
3631 static int
3632 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3633 {
3634         smb_info_t *si = pinfo->private_data;
3635         int fn_len;
3636         const char *fn;
3637         guint8 wc;
3638         guint16 bc;
3639
3640         WORD_COUNT;
3641
3642         /* 2 reserved bytes */
3643         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3644         offset += 2;
3645
3646         /* Creation time */
3647         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3648
3649         BYTE_COUNT;
3650
3651         /* buffer format */
3652         CHECK_BYTE_COUNT(1);
3653         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3654         COUNT_BYTES(1);
3655
3656         /* directory name */
3657         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3658                 FALSE, FALSE, &bc);
3659         if (fn == NULL)
3660                 goto endofcommand;
3661         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3662                 fn);
3663         COUNT_BYTES(fn_len);
3664
3665         if (check_col(pinfo->cinfo, COL_INFO)) {
3666                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3667         }
3668
3669         END_OF_SMB
3670
3671         return offset;
3672 }
3673
3674 static int
3675 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3676 {
3677         smb_info_t *si = pinfo->private_data;
3678         int fn_len;
3679         const char *fn;
3680         guint8 wc;
3681         guint16 bc, fid;
3682
3683         WORD_COUNT;
3684
3685         /* fid */
3686         fid = tvb_get_letohs(tvb, offset);
3687         add_fid(tvb, pinfo, tree, offset, 2, fid);
3688         offset += 2;
3689
3690         BYTE_COUNT;
3691
3692         /* buffer format */
3693         CHECK_BYTE_COUNT(1);
3694         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3695         COUNT_BYTES(1);
3696
3697         /* file name */
3698         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3699                 FALSE, FALSE, &bc);
3700         if (fn == NULL)
3701                 goto endofcommand;
3702         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3703                 fn);
3704         COUNT_BYTES(fn_len);
3705
3706         END_OF_SMB
3707
3708         return offset;
3709 }
3710
3711 static const value_string seek_mode_vals[] = {
3712         {0,     "From Start Of File"},
3713         {1,     "From Current Position"},
3714         {2,     "From End Of File"},
3715         {0,     NULL}
3716 };
3717
3718 static int
3719 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3720 {
3721         guint8 wc;
3722         guint16 bc, fid;
3723
3724         WORD_COUNT;
3725
3726         /* fid */
3727         fid = tvb_get_letohs(tvb, offset);
3728         add_fid(tvb, pinfo, tree, offset, 2, fid);
3729         offset += 2;
3730
3731         /* Seek Mode */
3732         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3733         offset += 2;
3734
3735         /* offset */
3736         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3737         offset += 4;
3738
3739         BYTE_COUNT;
3740
3741         END_OF_SMB
3742
3743         return offset;
3744 }
3745
3746 static int
3747 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3748 {
3749         guint8 wc;
3750         guint16 bc;
3751
3752         WORD_COUNT;
3753
3754         /* offset */
3755         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3756         offset += 4;
3757
3758         BYTE_COUNT;
3759
3760         END_OF_SMB
3761
3762         return offset;
3763 }
3764
3765 static int
3766 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3767 {
3768         guint8 wc;
3769         guint16 bc, fid;
3770
3771         WORD_COUNT;
3772
3773         /* fid */
3774         fid = tvb_get_letohs(tvb, offset);
3775         add_fid(tvb, pinfo, tree, offset, 2, fid);
3776         offset += 2;
3777
3778         /* create time */
3779         offset = dissect_smb_datetime(tvb, tree, offset,
3780                 hf_smb_create_time,
3781                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3782
3783         /* access time */
3784         offset = dissect_smb_datetime(tvb, tree, offset,
3785                 hf_smb_access_time,
3786                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3787
3788         /* last write time */
3789         offset = dissect_smb_datetime(tvb, tree, offset,
3790                 hf_smb_last_write_time,
3791                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3792
3793         BYTE_COUNT;
3794
3795         END_OF_SMB
3796
3797         return offset;
3798 }
3799
3800 static int
3801 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3802 {
3803         guint8 wc;
3804         guint16 bc;
3805
3806         WORD_COUNT;
3807
3808         /* create time */
3809         offset = dissect_smb_datetime(tvb, tree, offset,
3810                 hf_smb_create_time,
3811                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3812
3813         /* access time */
3814         offset = dissect_smb_datetime(tvb, tree, offset,
3815                 hf_smb_access_time,
3816                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3817
3818         /* last write time */
3819         offset = dissect_smb_datetime(tvb, tree, offset,
3820                 hf_smb_last_write_time,
3821                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3822
3823         /* data size */
3824         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3825         offset += 4;
3826
3827         /* allocation size */
3828         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3829         offset += 4;
3830
3831         /* File Attributes */
3832         offset = dissect_file_attributes(tvb, tree, offset, 2);
3833
3834         BYTE_COUNT;
3835
3836         END_OF_SMB
3837
3838         return offset;
3839 }
3840
3841 static int
3842 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3843 {
3844         guint8 wc;
3845         guint16 cnt=0;
3846         guint16 bc, fid;
3847
3848         WORD_COUNT;
3849
3850         /* fid */
3851         fid = tvb_get_letohs(tvb, offset);
3852         add_fid(tvb, pinfo, tree, offset, 2, fid);
3853         offset += 2;
3854
3855         /* write count */
3856         cnt = tvb_get_letohs(tvb, offset);
3857         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3858         offset += 2;
3859
3860         /* offset */
3861         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3862         offset += 4;
3863
3864         /* last write time */
3865         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3866
3867         if(wc==12){
3868                 /* 12 reserved bytes */
3869                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3870                 offset += 12;
3871         }
3872
3873         BYTE_COUNT;
3874
3875         /* 1 pad byte */
3876         CHECK_BYTE_COUNT(1);
3877         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3878         COUNT_BYTES(1);
3879
3880         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
3881         bc = 0; /* XXX */
3882
3883         END_OF_SMB
3884
3885         return offset;
3886 }
3887
3888 static int
3889 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3890 {
3891         guint8 wc;
3892         guint16 bc;
3893
3894         WORD_COUNT;
3895
3896         /* write count */
3897         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3898         offset += 2;
3899
3900         BYTE_COUNT;
3901
3902         END_OF_SMB
3903
3904         return offset;
3905 }
3906
3907 static int
3908 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3909 {
3910         guint8 wc;
3911         guint16 bc, fid;
3912         guint32 to;
3913
3914         WORD_COUNT;
3915
3916         /* fid */
3917         fid = tvb_get_letohs(tvb, offset);
3918         add_fid(tvb, pinfo, tree, offset, 2, fid);
3919         offset += 2;
3920
3921         /* offset */
3922         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3923         offset += 4;
3924
3925         /* max count */
3926         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3927         offset += 2;
3928
3929         /* min count */
3930         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3931         offset += 2;
3932
3933         /* timeout */
3934         to = tvb_get_letohl(tvb, offset);
3935         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3936         offset += 4;
3937
3938         /* 2 reserved bytes */
3939         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3940         offset += 2;
3941
3942         if(wc==10){
3943                 /* high offset */
3944                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3945                 offset += 4;
3946         }
3947
3948         BYTE_COUNT;
3949
3950         END_OF_SMB
3951
3952         return offset;
3953 }
3954
3955 static int
3956 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3957 {
3958         guint8 wc;
3959         guint16 bc;
3960
3961         WORD_COUNT;
3962
3963         /* units */
3964         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3965         offset += 2;
3966
3967         /* bpu */
3968         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3969         offset += 2;
3970
3971         /* block size */
3972         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3973         offset += 2;
3974
3975         /* free units */
3976         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3977         offset += 2;
3978
3979         /* 2 reserved bytes */
3980         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3981         offset += 2;
3982
3983         BYTE_COUNT;
3984
3985         END_OF_SMB
3986
3987         return offset;
3988 }
3989
3990 static int
3991 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3992 {
3993         guint8 wc;
3994         guint16 bc, fid;
3995
3996         WORD_COUNT;
3997
3998         /* fid */
3999         fid = tvb_get_letohs(tvb, offset);
4000         add_fid(tvb, pinfo, tree, offset, 2, fid);
4001         offset += 2;
4002
4003         /* offset */
4004         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4005         offset += 4;
4006
4007         /* max count */
4008         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4009         offset += 2;
4010
4011         /* min count */
4012         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4013         offset += 2;
4014
4015         /* 6 reserved bytes */
4016         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
4017         offset += 6;
4018
4019         BYTE_COUNT;
4020
4021         END_OF_SMB
4022
4023         return offset;
4024 }
4025
4026 static int
4027 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4028 {
4029         guint16 datalen=0, bc;
4030         guint8 wc;
4031
4032         WORD_COUNT;
4033
4034         /* offset */
4035         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4036         offset += 4;
4037
4038         /* count */
4039         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4040         offset += 2;
4041
4042         /* 2 reserved bytes */
4043         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4044         offset += 2;
4045
4046         /* data compaction mode */
4047         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4048         offset += 2;
4049
4050         /* 2 reserved bytes */
4051         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4052         offset += 2;
4053
4054         /* data len */
4055         datalen = tvb_get_letohs(tvb, offset);
4056         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4057         offset += 2;
4058
4059         /* data offset */
4060         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4061         offset += 2;
4062
4063         BYTE_COUNT;
4064
4065         /* file data */
4066         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4067         bc = 0;
4068
4069         END_OF_SMB
4070
4071         return offset;
4072 }
4073
4074
4075 static const true_false_string tfs_write_mode_write_through = {
4076         "WRITE THROUGH requested",
4077         "Write through not requested"
4078 };
4079 static const true_false_string tfs_write_mode_return_remaining = {
4080         "RETURN REMAINING (pipe/dev) requested",
4081         "DON'T return remaining (pipe/dev)"
4082 };
4083 static const true_false_string tfs_write_mode_raw = {
4084         "Use WriteRawNamedPipe (pipe)",
4085         "DON'T use WriteRawNamedPipe (pipe)"
4086 };
4087 static const true_false_string tfs_write_mode_message_start = {
4088         "This is the START of a MESSAGE (pipe)",
4089         "This is NOT the start of a message (pipe)"
4090 };
4091 static const true_false_string tfs_write_mode_connectionless = {
4092         "CONNECTIONLESS mode requested",
4093         "Connectionless mode NOT requested"
4094 };
4095
4096 #define WRITE_MODE_CONNECTIONLESS       0x0080
4097 #define WRITE_MODE_MESSAGE_START        0x0008
4098 #define WRITE_MODE_RAW                  0x0004
4099 #define WRITE_MODE_RETURN_REMAINING     0x0002
4100 #define WRITE_MODE_WRITE_THROUGH        0x0001
4101
4102 static int
4103 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4104 {
4105         guint16 mask;
4106         proto_item *item = NULL;
4107         proto_tree *tree = NULL;
4108
4109         mask = tvb_get_letohs(tvb, offset);
4110
4111         if(parent_tree){
4112                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4113                         "Write Mode: 0x%04x", mask);
4114                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
4115         }
4116
4117         if(bm&WRITE_MODE_CONNECTIONLESS){
4118                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
4119                         tvb, offset, 2, mask);
4120         }
4121         if(bm&WRITE_MODE_MESSAGE_START){
4122                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
4123                         tvb, offset, 2, mask);
4124         }
4125         if(bm&WRITE_MODE_RAW){
4126                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
4127                         tvb, offset, 2, mask);
4128         }
4129         if(bm&WRITE_MODE_RETURN_REMAINING){
4130                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
4131                         tvb, offset, 2, mask);
4132         }
4133         if(bm&WRITE_MODE_WRITE_THROUGH){
4134                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4135                         tvb, offset, 2, mask);
4136         }
4137
4138         offset += 2;
4139         return offset;
4140 }
4141
4142 static int
4143 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4144 {
4145         guint32 to;
4146         guint16 datalen=0, bc, fid;
4147         guint8 wc;
4148
4149         WORD_COUNT;
4150
4151         /* fid */
4152         fid = tvb_get_letohs(tvb, offset);
4153         add_fid(tvb, pinfo, tree, offset, 2, fid);
4154         offset += 2;
4155
4156         /* total data length */
4157         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4158         offset += 2;
4159
4160         /* 2 reserved bytes */
4161         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4162         offset += 2;
4163
4164         /* offset */
4165         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4166         offset += 4;
4167
4168         /* timeout */
4169         to = tvb_get_letohl(tvb, offset);
4170         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4171         offset += 4;
4172
4173         /* mode */
4174         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4175
4176         /* 4 reserved bytes */
4177         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4178         offset += 4;
4179
4180         /* data len */
4181         datalen = tvb_get_letohs(tvb, offset);
4182         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4183         offset += 2;
4184
4185         /* data offset */
4186         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4187         offset += 2;
4188
4189         BYTE_COUNT;
4190
4191         /* file data */
4192         /* XXX - use the data offset to determine where the data starts? */
4193         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4194         bc = 0;
4195
4196         END_OF_SMB
4197
4198         return offset;
4199 }
4200
4201 static int
4202 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4203 {
4204         guint8 wc;
4205         guint16 bc;
4206
4207         WORD_COUNT;
4208
4209         /* remaining */
4210         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4211         offset += 2;
4212
4213         BYTE_COUNT;
4214
4215         END_OF_SMB
4216
4217         return offset;
4218 }
4219
4220 static int
4221 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4222 {
4223         guint32 to;
4224         guint16 datalen=0, bc, fid;
4225         guint8 wc;
4226
4227         WORD_COUNT;
4228
4229         /* fid */
4230         fid = tvb_get_letohs(tvb, offset);
4231         add_fid(tvb, pinfo, tree, offset, 2, fid);
4232         offset += 2;
4233
4234         /* total data length */
4235         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4236         offset += 2;
4237
4238         /* 2 reserved bytes */
4239         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4240         offset += 2;
4241
4242         /* offset */
4243         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4244         offset += 4;
4245
4246         /* timeout */
4247         to = tvb_get_letohl(tvb, offset);
4248         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4249         offset += 4;
4250
4251         /* mode */
4252         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
4253
4254         /* request mask */
4255         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
4256         offset += 4;
4257
4258         /* data len */
4259         datalen = tvb_get_letohs(tvb, offset);
4260         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4261         offset += 2;
4262
4263         /* data offset */
4264         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4265         offset += 2;
4266
4267         BYTE_COUNT;
4268
4269         /* file data */
4270         /* XXX - use the data offset to determine where the data starts? */
4271         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4272         bc = 0;
4273
4274         END_OF_SMB
4275
4276         return offset;
4277 }
4278
4279 static int
4280 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4281 {
4282         guint8 wc;
4283         guint16 bc;
4284
4285         WORD_COUNT;
4286
4287         /* response mask */
4288         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
4289         offset += 4;
4290
4291         BYTE_COUNT;
4292
4293         END_OF_SMB
4294
4295         return offset;
4296 }
4297
4298 static int
4299 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4300 {
4301         guint8 wc;
4302         guint16 bc;
4303
4304         WORD_COUNT;
4305
4306         /* sid */
4307         proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
4308         offset += 2;
4309
4310         BYTE_COUNT;
4311
4312         END_OF_SMB
4313
4314         return offset;
4315 }
4316
4317 static int
4318 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
4319     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4320     gboolean has_find_id)
4321 {
4322         proto_item *item = NULL;
4323         proto_tree *tree = NULL;
4324         smb_info_t *si = pinfo->private_data;
4325         int fn_len;
4326         const char *fn;
4327         char fname[11+1];
4328
4329         if(parent_tree){
4330                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
4331                         "Resume Key");
4332                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
4333         }
4334
4335         /* reserved byte */
4336         CHECK_BYTE_COUNT_SUBR(1);
4337         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4338         COUNT_BYTES_SUBR(1);
4339
4340         /* file name */
4341         fn_len = 11;
4342         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4343                 TRUE, TRUE, bcp);
4344         CHECK_STRING_SUBR(fn);
4345         /* ensure that it's null-terminated */
4346         strncpy(fname, fn, 11);
4347         fname[11] = '\0';
4348         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
4349                 fname);
4350         COUNT_BYTES_SUBR(fn_len);
4351
4352         if (has_find_id) {
4353                 CHECK_BYTE_COUNT_SUBR(1);
4354                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
4355                 COUNT_BYTES_SUBR(1);
4356
4357                 /* server cookie */
4358                 CHECK_BYTE_COUNT_SUBR(4);
4359                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
4360                 COUNT_BYTES_SUBR(4);
4361         } else {
4362                 /* server cookie */
4363                 CHECK_BYTE_COUNT_SUBR(5);
4364                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
4365                 COUNT_BYTES_SUBR(5);
4366         }
4367
4368         /* client cookie */
4369         CHECK_BYTE_COUNT_SUBR(4);
4370         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
4371         COUNT_BYTES_SUBR(4);
4372
4373         *trunc = FALSE;
4374         return offset;
4375 }
4376
4377 static int
4378 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
4379     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4380     gboolean has_find_id)
4381 {
4382         proto_item *item = NULL;
4383         proto_tree *tree = NULL;
4384         smb_info_t *si = pinfo->private_data;
4385         int fn_len;
4386         const char *fn;
4387         char fname[13+1];
4388
4389         if(parent_tree){
4390                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
4391                         "Directory Information");
4392                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
4393         }
4394
4395         /* resume key */
4396         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
4397             trunc, has_find_id);
4398         if (*trunc)
4399                 return offset;
4400
4401         /* File Attributes */
4402         CHECK_BYTE_COUNT_SUBR(1);
4403         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
4404         *bcp -= 1;
4405
4406         /* last write time */
4407         CHECK_BYTE_COUNT_SUBR(4);
4408         offset = dissect_smb_datetime(tvb, tree, offset,
4409                 hf_smb_last_write_time,
4410                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
4411                 TRUE);
4412         *bcp -= 4;
4413
4414         /* File Size */
4415         CHECK_BYTE_COUNT_SUBR(4);
4416         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4417         COUNT_BYTES_SUBR(4);
4418
4419         /* file name */
4420         fn_len = 13;
4421         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4422                 TRUE, TRUE, bcp);
4423         CHECK_STRING_SUBR(fn);
4424         /* ensure that it's null-terminated */
4425         strncpy(fname, fn, 13);
4426         fname[13] = '\0';
4427         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4428                 fname);
4429         COUNT_BYTES_SUBR(fn_len);
4430
4431         *trunc = FALSE;
4432         return offset;
4433 }
4434
4435
4436 static int
4437 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
4438     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4439     gboolean has_find_id)
4440 {
4441         smb_info_t *si = pinfo->private_data;
4442         int fn_len;
4443         const char *fn;
4444         guint16 rkl;
4445         guint8 wc;
4446         guint16 bc;
4447         gboolean trunc;
4448
4449         WORD_COUNT;
4450
4451         /* max count */
4452         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4453         offset += 2;
4454
4455         /* Search Attributes */
4456         offset = dissect_search_attributes(tvb, tree, offset);
4457
4458         BYTE_COUNT;
4459
4460         /* buffer format */
4461         CHECK_BYTE_COUNT(1);
4462         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4463         COUNT_BYTES(1);
4464
4465         /* file name */
4466         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4467                 TRUE, FALSE, &bc);
4468         if (fn == NULL)
4469                 goto endofcommand;
4470         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4471                 fn);
4472         COUNT_BYTES(fn_len);
4473
4474         if (check_col(pinfo->cinfo, COL_INFO)) {
4475                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", fn);
4476         }
4477
4478         /* buffer format */
4479         CHECK_BYTE_COUNT(1);
4480         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4481         COUNT_BYTES(1);
4482
4483         /* resume key length */
4484         CHECK_BYTE_COUNT(2);
4485         rkl = tvb_get_letohs(tvb, offset);
4486         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
4487         COUNT_BYTES(2);
4488
4489         /* resume key */
4490         if(rkl){
4491                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
4492                     &bc, &trunc, has_find_id);
4493                 if (trunc)
4494                         goto endofcommand;
4495         }
4496
4497         END_OF_SMB
4498
4499         return offset;
4500 }
4501
4502 static int
4503 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4504     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4505 {
4506         return dissect_search_find_request(tvb, pinfo, tree, offset,
4507             smb_tree, FALSE);
4508 }
4509
4510 static int
4511 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4512     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4513 {
4514         return dissect_search_find_request(tvb, pinfo, tree, offset,
4515             smb_tree, TRUE);
4516 }
4517
4518 static int
4519 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4520     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4521 {
4522         return dissect_search_find_request(tvb, pinfo, tree, offset,
4523             smb_tree, TRUE);
4524 }
4525
4526 static int
4527 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4528     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4529     gboolean has_find_id)
4530 {
4531         guint16 count=0;
4532         guint8 wc;
4533         guint16 bc;
4534         gboolean trunc;
4535
4536         WORD_COUNT;
4537
4538         /* count */
4539         count = tvb_get_letohs(tvb, offset);
4540         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
4541         offset += 2;
4542
4543         BYTE_COUNT;
4544
4545         /* buffer format */
4546         CHECK_BYTE_COUNT(1);
4547         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4548         COUNT_BYTES(1);
4549
4550         /* data len */
4551         CHECK_BYTE_COUNT(2);
4552         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4553         COUNT_BYTES(2);
4554
4555         while(count--){
4556                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
4557                     &bc, &trunc, has_find_id);
4558                 if (trunc)
4559                         goto endofcommand;
4560         }
4561
4562         END_OF_SMB
4563
4564         return offset;
4565 }
4566
4567 static int
4568 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4569 {
4570         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4571             FALSE);
4572 }
4573
4574 static int
4575 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4576 {
4577         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4578             TRUE);
4579 }
4580
4581 static int
4582 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4583     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4584 {
4585         guint8 wc;
4586         guint16 bc;
4587         guint16 data_len;
4588
4589         WORD_COUNT;
4590
4591         /* reserved */
4592         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4593         offset += 2;
4594
4595         BYTE_COUNT;
4596
4597         /* buffer format */
4598         CHECK_BYTE_COUNT(1);
4599         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4600         COUNT_BYTES(1);
4601
4602         /* data len */
4603         CHECK_BYTE_COUNT(2);
4604         data_len = tvb_get_ntohs(tvb, offset);
4605         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
4606         COUNT_BYTES(2);
4607
4608         if (data_len != 0) {
4609                 CHECK_BYTE_COUNT(data_len);
4610                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
4611                     data_len, TRUE);
4612                 COUNT_BYTES(data_len);
4613         }
4614
4615         END_OF_SMB
4616
4617         return offset;
4618 }
4619
4620 static const value_string locking_ol_vals[] = {
4621         {0,     "Client is not holding oplock on this file"},
4622         {1,     "Level 2 oplock currently held by client"},
4623         {0, NULL}
4624 };
4625
4626 static const true_false_string tfs_lock_type_large = {
4627         "Large file locking format requested",
4628         "Large file locking format not requested"
4629 };
4630 static const true_false_string tfs_lock_type_cancel = {
4631         "Cancel outstanding lock request",
4632         "Don't cancel outstanding lock request"
4633 };
4634 static const true_false_string tfs_lock_type_change = {
4635         "Change lock type",
4636         "Don't change lock type"
4637 };
4638 static const true_false_string tfs_lock_type_oplock = {
4639         "This is an oplock break notification/response",
4640         "This is not an oplock break notification/response"
4641 };
4642 static const true_false_string tfs_lock_type_shared = {
4643         "This is a shared lock",
4644         "This is an exclusive lock"
4645 };
4646 static int
4647 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4648 {
4649         guint8  wc, cmd=0xff, lt=0;
4650         guint16 andxoffset=0, un=0, ln=0, bc, fid;
4651         guint32 to;
4652         proto_item *litem = NULL;
4653         proto_tree *ltree = NULL;
4654         proto_item *it = NULL;
4655         proto_tree *tr = NULL;
4656         int old_offset = offset;
4657
4658         WORD_COUNT;
4659
4660         /* next smb command */
4661         cmd = tvb_get_guint8(tvb, offset);
4662         if(cmd!=0xff){
4663                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4664         } else {
4665                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
4666         }
4667         offset += 1;
4668
4669         /* reserved byte */
4670         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4671         offset += 1;
4672
4673         /* andxoffset */
4674         andxoffset = tvb_get_letohs(tvb, offset);
4675         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4676         offset += 2;
4677
4678         /* fid */
4679         fid = tvb_get_letohs(tvb, offset);
4680         add_fid(tvb, pinfo, tree, offset, 2, fid);
4681         offset += 2;
4682
4683         /* lock type */
4684         lt = tvb_get_guint8(tvb, offset);
4685         if(tree){
4686                 litem = proto_tree_add_text(tree, tvb, offset, 1,
4687                         "Lock Type: 0x%02x", lt);
4688                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
4689         }
4690         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
4691                 tvb, offset, 1, lt);
4692         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
4693                 tvb, offset, 1, lt);
4694         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
4695                 tvb, offset, 1, lt);
4696         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
4697                 tvb, offset, 1, lt);
4698         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
4699                 tvb, offset, 1, lt);
4700         offset += 1;
4701
4702         /* oplock level */
4703         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
4704         offset += 1;
4705
4706         /* timeout */
4707         to = tvb_get_letohl(tvb, offset);
4708         if (to == 0)
4709                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
4710         else if (to == 0xffffffff)
4711                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
4712         else
4713                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4714         offset += 4;
4715
4716         /* number of unlocks */
4717         un = tvb_get_letohs(tvb, offset);
4718         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
4719         offset += 2;
4720
4721         /* number of locks */
4722         ln = tvb_get_letohs(tvb, offset);
4723         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
4724         offset += 2;
4725
4726         BYTE_COUNT;
4727
4728         /* unlocks */
4729         if(un){
4730                 old_offset = offset;
4731
4732                 it = proto_tree_add_text(tree, tvb, offset, -1,
4733                         "Unlocks");
4734                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
4735                 while(un--){
4736                         proto_item *litem = NULL;
4737                         proto_tree *ltree = NULL;
4738                         if(lt&0x10){
4739                                 char buf[8];
4740                                 guint32 val;
4741
4742                                 /* large lock format */
4743                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4744                                         "Unlock");
4745                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4746
4747                                 /* PID */
4748                                 CHECK_BYTE_COUNT(2);
4749                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4750                                 COUNT_BYTES(2);
4751
4752                                 /* 2 reserved bytes */
4753                                 CHECK_BYTE_COUNT(2);
4754                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4755                                 COUNT_BYTES(2);
4756
4757                                 /* offset */
4758                                 CHECK_BYTE_COUNT(8);
4759                                 val=tvb_get_letohl(tvb, offset);
4760                                 buf[3]=(val>>24)&0xff;
4761                                 buf[2]=(val>>16)&0xff;
4762                                 buf[1]=(val>> 8)&0xff;
4763                                 buf[0]=(val    )&0xff;
4764                                 val=tvb_get_letohl(tvb, offset+4);
4765                                 buf[7]=(val>>24)&0xff;
4766                                 buf[6]=(val>>16)&0xff;
4767                                 buf[5]=(val>> 8)&0xff;
4768                                 buf[4]=(val    )&0xff;
4769                                 proto_tree_add_string(ltree, hf_smb_lock_long_offset, tvb, offset, 8, u64toa(buf));
4770                                 COUNT_BYTES(8);
4771
4772                                 /* length */
4773                                 CHECK_BYTE_COUNT(8);
4774                                 val=tvb_get_letohl(tvb, offset);
4775                                 buf[3]=(val>>24)&0xff;
4776                                 buf[2]=(val>>16)&0xff;
4777                                 buf[1]=(val>> 8)&0xff;
4778                                 buf[0]=(val    )&0xff;
4779                                 val=tvb_get_letohl(tvb, offset+4);
4780                                 buf[7]=(val>>24)&0xff;
4781                                 buf[6]=(val>>16)&0xff;
4782                                 buf[5]=(val>> 8)&0xff;
4783                                 buf[4]=(val    )&0xff;
4784                                 proto_tree_add_string(ltree, hf_smb_lock_long_length, tvb, offset, 8, u64toa(buf));
4785                                 COUNT_BYTES(8);
4786                         } else {
4787                                 /* normal lock format */
4788                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4789                                         "Unlock");
4790                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4791
4792                                 /* PID */
4793                                 CHECK_BYTE_COUNT(2);
4794                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4795                                 COUNT_BYTES(2);
4796
4797                                 /* offset */
4798                                 CHECK_BYTE_COUNT(4);
4799                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4800                                 COUNT_BYTES(4);
4801
4802                                 /* lock count */
4803                                 CHECK_BYTE_COUNT(4);
4804                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4805                                 COUNT_BYTES(4);
4806                         }
4807                 }
4808                 proto_item_set_len(it, offset-old_offset);
4809                 it = NULL;
4810         }
4811
4812         /* locks */
4813         if(ln){
4814                 old_offset = offset;
4815
4816                 it = proto_tree_add_text(tree, tvb, offset, -1,
4817                         "Locks");
4818                 tr = proto_item_add_subtree(it, ett_smb_locks);
4819                 while(ln--){
4820                         proto_item *litem = NULL;
4821                         proto_tree *ltree = NULL;
4822                         if(lt&0x10){
4823                                 char buf[8];
4824                                 guint32 val;
4825
4826                                 /* large lock format */
4827                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4828                                         "Lock");
4829                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
4830
4831                                 /* PID */
4832                                 CHECK_BYTE_COUNT(2);
4833                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4834                                 COUNT_BYTES(2);
4835
4836                                 /* 2 reserved bytes */
4837                                 CHECK_BYTE_COUNT(2);
4838                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4839                                 COUNT_BYTES(2);
4840
4841                                 /* offset */
4842                                 CHECK_BYTE_COUNT(8);
4843                                 val=tvb_get_letohl(tvb, offset);
4844                                 buf[3]=(val    )&0xff;
4845                                 buf[2]=(val>> 8)&0xff;
4846                                 buf[1]=(val>>16)&0xff;
4847                                 buf[0]=(val>>24)&0xff;
4848                                 val=tvb_get_letohl(tvb, offset+4);
4849                                 buf[7]=(val    )&0xff;
4850                                 buf[6]=(val>> 8)&0xff;
4851                                 buf[5]=(val>>16)&0xff;
4852                                 buf[4]=(val>>24)&0xff;
4853                                 proto_tree_add_string(ltree, hf_smb_lock_long_offset, tvb, offset, 8, u64toa(buf));
4854                                 COUNT_BYTES(8);
4855
4856                                 /* length */
4857                                 CHECK_BYTE_COUNT(8);
4858                                 val=tvb_get_letohl(tvb, offset);
4859                                 buf[3]=(val    )&0xff;
4860                                 buf[2]=(val>> 8)&0xff;
4861                                 buf[1]=(val>>16)&0xff;
4862                                 buf[0]=(val>>24)&0xff;
4863                                 val=tvb_get_letohl(tvb, offset+4);
4864                                 buf[7]=(val    )&0xff;
4865                                 buf[6]=(val>> 8)&0xff;
4866                                 buf[5]=(val>>16)&0xff;
4867                                 buf[4]=(val>>24)&0xff;
4868                                 proto_tree_add_string(ltree, hf_smb_lock_long_length, tvb, offset, 8, u64toa(buf));
4869                                 COUNT_BYTES(8);
4870                         } else {
4871                                 /* normal lock format */
4872                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4873                                         "Unlock");
4874                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4875
4876                                 /* PID */
4877                                 CHECK_BYTE_COUNT(2);
4878                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4879                                 COUNT_BYTES(2);
4880
4881                                 /* offset */
4882                                 CHECK_BYTE_COUNT(4);
4883                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4884                                 COUNT_BYTES(4);
4885
4886                                 /* lock count */
4887                                 CHECK_BYTE_COUNT(4);
4888                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4889                                 COUNT_BYTES(4);
4890                         }
4891                 }
4892                 proto_item_set_len(it, offset-old_offset);
4893                 it = NULL;
4894         }
4895
4896         END_OF_SMB
4897
4898         if (it != NULL) {
4899                 /*
4900                  * We ran out of byte count in the middle of dissecting
4901                  * the locks or the unlocks; set the site of the item
4902                  * we were dissecting.
4903                  */
4904                 proto_item_set_len(it, offset-old_offset);
4905         }
4906
4907         /* call AndXCommand (if there are any) */
4908         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4909
4910         return offset;
4911 }
4912
4913 static int
4914 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4915 {
4916         guint8  wc, cmd=0xff;
4917         guint16 andxoffset=0;
4918         guint16 bc;
4919
4920         WORD_COUNT;
4921
4922         /* next smb command */
4923         cmd = tvb_get_guint8(tvb, offset);
4924         if(cmd!=0xff){
4925                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4926         } else {
4927                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
4928         }
4929         offset += 1;
4930
4931         /* reserved byte */
4932         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4933         offset += 1;
4934
4935         /* andxoffset */
4936         andxoffset = tvb_get_letohs(tvb, offset);
4937         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4938         offset += 2;
4939
4940         BYTE_COUNT;
4941
4942         END_OF_SMB
4943
4944         /* call AndXCommand (if there are any) */
4945         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4946
4947         return offset;
4948 }
4949
4950
4951 static const value_string oa_open_vals[] = {
4952         { 0,            "No action taken?"},
4953         { 1,            "The file existed and was opened"},
4954         { 2,            "The file did not exist but was created"},
4955         { 3,            "The file existed and was truncated"},
4956         { 0x8001,       "The file existed and was opened, and an OpLock was granted"}, 
4957         { 0x8002,       "The file did not exist but was created, and an OpLock was granted"},
4958         { 0x8002,       "The file existed and was truncated, and an OpLock was granted"},
4959         {0,     NULL}
4960 };
4961 static const true_false_string tfs_oa_lock = {
4962         "File is currently opened only by this user",
4963         "File is opened by another user (or mode not supported by server)"
4964 };
4965 static int
4966 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
4967 {
4968         guint16 mask;
4969         proto_item *item = NULL;
4970         proto_tree *tree = NULL;
4971
4972         mask = tvb_get_letohs(tvb, offset);
4973
4974         if(parent_tree){
4975                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4976                         "Action: 0x%04x", mask);
4977                 tree = proto_item_add_subtree(item, ett_smb_open_action);
4978         }
4979
4980         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
4981                 tvb, offset, 2, mask);
4982         proto_tree_add_uint(tree, hf_smb_open_action_open,
4983                 tvb, offset, 2, mask);
4984
4985         offset += 2;
4986
4987         return offset;
4988 }
4989
4990 static const true_false_string tfs_open_flags_add_info = {
4991         "Additional information requested",
4992         "Additional information not requested"
4993 };
4994 static const true_false_string tfs_open_flags_ex_oplock = {
4995         "Exclusive oplock requested",
4996         "Exclusive oplock not requested"
4997 };
4998 static const true_false_string tfs_open_flags_batch_oplock = {
4999         "Batch oplock requested",
5000         "Batch oplock not requested"
5001 };
5002 static const true_false_string tfs_open_flags_ealen = {
5003         "Total length of EAs requested",
5004         "Total length of EAs not requested"
5005 };
5006 static int
5007 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
5008 {
5009         guint16 mask;
5010         proto_item *item = NULL;
5011         proto_tree *tree = NULL;
5012
5013         mask = tvb_get_letohs(tvb, offset);
5014
5015         if(parent_tree){
5016                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5017                         "Flags: 0x%04x", mask);
5018                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
5019         }
5020
5021         if(bm&0x0001){
5022                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
5023                         tvb, offset, 2, mask);
5024         }
5025         if(bm&0x0002){
5026                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
5027                         tvb, offset, 2, mask);
5028         }
5029         if(bm&0x0004){
5030                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
5031                         tvb, offset, 2, mask);
5032         }
5033         if(bm&0x0008){
5034                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
5035                         tvb, offset, 2, mask);
5036         }
5037
5038         offset += 2;
5039
5040         return offset;
5041 }
5042
5043 static const value_string filetype_vals[] = {
5044         { 0,            "Disk file or directory"},
5045         { 1,            "Named pipe in byte mode"},
5046         { 2,            "Named pipe in message mode"},
5047         { 3,            "Spooled printer"},
5048         {0, NULL}
5049 };
5050 static int
5051 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5052 {
5053         guint8  wc, cmd=0xff;
5054         guint16 andxoffset=0, bc;
5055         smb_info_t *si = pinfo->private_data;
5056         int fn_len;
5057         const char *fn;
5058
5059         WORD_COUNT;
5060
5061         /* next smb command */
5062         cmd = tvb_get_guint8(tvb, offset);
5063         if(cmd!=0xff){
5064                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5065         } else {
5066                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5067         }
5068         offset += 1;
5069
5070         /* reserved byte */
5071         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5072         offset += 1;
5073
5074         /* andxoffset */
5075         andxoffset = tvb_get_letohs(tvb, offset);
5076         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5077         offset += 2;
5078
5079         /* open flags */
5080         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
5081
5082         /* desired access */
5083         offset = dissect_access(tvb, tree, offset, "Desired");
5084
5085         /* Search Attributes */
5086         offset = dissect_search_attributes(tvb, tree, offset);
5087
5088         /* File Attributes */
5089         offset = dissect_file_attributes(tvb, tree, offset, 2);
5090
5091         /* creation time */
5092         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
5093
5094         /* open function */
5095         offset = dissect_open_function(tvb, tree, offset);
5096
5097         /* allocation size */
5098         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
5099         offset += 4;
5100
5101         /* 8 reserved bytes */
5102         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
5103         offset += 8;
5104
5105         BYTE_COUNT;
5106
5107         /* file name */
5108         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5109                 FALSE, FALSE, &bc);
5110         if (fn == NULL)
5111                 goto endofcommand;
5112         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5113                 fn);
5114         COUNT_BYTES(fn_len);
5115
5116         if (check_col(pinfo->cinfo, COL_INFO)) {
5117                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
5118         }
5119
5120         END_OF_SMB
5121
5122         /* call AndXCommand (if there are any) */
5123         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5124
5125         return offset;
5126 }
5127
5128 static const true_false_string tfs_ipc_state_nonblocking = {
5129         "Reads/writes return immediately if no data available",
5130         "Reads/writes block if no data available"
5131 };
5132 static const value_string ipc_state_endpoint_vals[] = {
5133         { 0,            "Consumer end of pipe"},
5134         { 1,            "Server end of pipe"},
5135         {0,     NULL}
5136 };
5137 static const value_string ipc_state_pipe_type_vals[] = {
5138         { 0,            "Byte stream pipe"},
5139         { 1,            "Message pipe"},
5140         {0,     NULL}
5141 };
5142 static const value_string ipc_state_read_mode_vals[] = {
5143         { 0,            "Read pipe as a byte stream"},
5144         { 1,            "Read messages from pipe"},
5145         {0,     NULL}
5146 };
5147
5148 int
5149 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
5150     gboolean setstate)
5151 {
5152         guint16 mask;
5153         proto_item *item = NULL;
5154         proto_tree *tree = NULL;
5155
5156         mask = tvb_get_letohs(tvb, offset);
5157
5158         if(parent_tree){
5159                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5160                         "IPC State: 0x%04x", mask);
5161                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
5162         }
5163
5164         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
5165                 tvb, offset, 2, mask);
5166         if (!setstate) {
5167                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
5168                         tvb, offset, 2, mask);
5169                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
5170                         tvb, offset, 2, mask);
5171         }
5172         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
5173                 tvb, offset, 2, mask);
5174         if (!setstate) {
5175                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
5176                         tvb, offset, 2, mask);
5177         }
5178
5179         offset += 2;
5180
5181         return offset;
5182 }
5183
5184 static int
5185 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5186 {
5187         guint8  wc, cmd=0xff;
5188         guint16 andxoffset=0, bc;
5189         guint16 fid;
5190
5191         WORD_COUNT;
5192
5193         /* next smb command */
5194         cmd = tvb_get_guint8(tvb, offset);
5195         if(cmd!=0xff){
5196                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5197         } else {
5198                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5199         }
5200         offset += 1;
5201
5202         /* reserved byte */
5203         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5204         offset += 1;
5205
5206         /* andxoffset */
5207         andxoffset = tvb_get_letohs(tvb, offset);
5208         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5209         offset += 2;
5210
5211         /* fid */
5212         fid = tvb_get_letohs(tvb, offset);
5213         add_fid(tvb, pinfo, tree, offset, 2, fid);
5214         offset += 2;
5215
5216         /* File Attributes */
5217         offset = dissect_file_attributes(tvb, tree, offset, 2);
5218
5219         /* last write time */
5220         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
5221
5222         /* File Size */
5223         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5224         offset += 4;
5225
5226         /* granted access */
5227         offset = dissect_access(tvb, tree, offset, "Granted");
5228
5229         /* File Type */
5230         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
5231         offset += 2;
5232
5233         /* IPC State */
5234         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
5235
5236         /* open_action */
5237         offset = dissect_open_action(tvb, tree, offset);
5238
5239         /* server fid */
5240         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
5241         offset += 4;
5242
5243         /* 2 reserved bytes */
5244         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5245         offset += 2;
5246
5247         BYTE_COUNT;
5248
5249         END_OF_SMB
5250
5251         /* call AndXCommand (if there are any) */
5252         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5253
5254         return offset;
5255 }
5256
5257 static int
5258 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5259 {
5260         guint8  wc, cmd=0xff;
5261         guint16 andxoffset=0, bc, maxcnt_low, maxcnt_high;
5262         guint32 maxcnt=0;
5263         guint32 ofs = 0;
5264         smb_info_t *si;
5265         unsigned int fid;
5266
5267         WORD_COUNT;
5268
5269         /* next smb command */
5270         cmd = tvb_get_guint8(tvb, offset);
5271         if(cmd!=0xff){
5272                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5273         } else {
5274                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5275         }
5276         offset += 1;
5277
5278         /* reserved byte */
5279         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5280         offset += 1;
5281
5282         /* andxoffset */
5283         andxoffset = tvb_get_letohs(tvb, offset);
5284         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5285         offset += 2;
5286
5287         /* fid */
5288         fid = tvb_get_letohs(tvb, offset);
5289         add_fid(tvb, pinfo, tree, offset, 2, fid);
5290         offset += 2;
5291         if (!pinfo->fd->flags.visited) {
5292                 /* remember the FID for the processing of the response */
5293                 si = (smb_info_t *)pinfo->private_data;
5294                 si->sip->extra_info=(void *)fid;
5295         }
5296
5297         /* offset */
5298         ofs = tvb_get_letohl(tvb, offset);
5299         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5300         offset += 4;
5301
5302         /* max count low */
5303         maxcnt_low = tvb_get_letohs(tvb, offset);
5304         proto_tree_add_uint(tree, hf_smb_max_count_low, tvb, offset, 2, maxcnt_low);
5305         offset += 2;
5306
5307         /* min count */
5308         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
5309         offset += 2;
5310
5311         /*
5312          * max count high
5313          *
5314          * XXX - we should really only do this in case we have seen
5315          * LARGE FILE being negotiated.  Unfortunately, we might not
5316          * have seen the negotiation phase in the capture....
5317          *
5318          * XXX - this is shown as a ULONG in the SNIA SMB spec, i.e.
5319          * it's 32 bits, but the description says "High 16 bits of
5320          * MaxCount if CAP_LARGE_READX".
5321          *
5322          * The SMB File Sharing Protocol Extensions Version 2.0,
5323          * Document Version 3.3 spec doesn't speak of an extra 16
5324          * bits in max count, but it does show a 32-bit timeout
5325          * after the min count field.
5326          *
5327          * Perhaps the 32-bit timeout field was hijacked as a 16-bit
5328          * high count and a 16-bit reserved field.
5329          */
5330         /* Amasingly enough, this really is 4 bytes, according to the SNIA spec */
5331         maxcnt_high = tvb_get_letohl(tvb, offset);
5332         proto_tree_add_uint(tree, hf_smb_max_count_high, tvb, offset, 4, maxcnt_high);
5333         offset += 4;
5334
5335         maxcnt=maxcnt_high;
5336         maxcnt=(maxcnt<<16)|maxcnt_low;
5337
5338         if (check_col(pinfo->cinfo, COL_INFO))
5339                 col_append_fstr(pinfo->cinfo, COL_INFO,
5340                                 ", %u byte%s at offset %u", maxcnt,
5341                                 (maxcnt == 1) ? "" : "s", ofs);
5342
5343         /* remaining */
5344         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5345         offset += 2;
5346
5347         if(wc==12){
5348                 /* high offset */
5349                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5350                 offset += 4;
5351         }
5352
5353         BYTE_COUNT;
5354
5355         END_OF_SMB
5356
5357         /* call AndXCommand (if there are any) */
5358         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5359
5360         return offset;
5361 }
5362
5363 static int
5364 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5365 {
5366         guint8  wc, cmd=0xff;
5367         guint16 andxoffset=0, bc, datalen_low, datalen_high, dataoffset=0;
5368         guint32 datalen=0;
5369         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5370         int fid=0;
5371
5372         WORD_COUNT;
5373
5374         /* next smb command */
5375         cmd = tvb_get_guint8(tvb, offset);
5376         if(cmd!=0xff){
5377                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5378         } else {
5379                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5380         }
5381         offset += 1;
5382
5383         /* reserved byte */
5384         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5385         offset += 1;
5386
5387         /* andxoffset */
5388         andxoffset = tvb_get_letohs(tvb, offset);
5389         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5390         offset += 2;
5391
5392         /* If we have seen the request, then print which FID this refers to */
5393         /* first check if we have seen the request */
5394         if(si->sip != NULL && si->sip->frame_req>0){
5395                 fid=(int)si->sip->extra_info;
5396                 add_fid(tvb, pinfo, tree, 0, 0, fid);
5397         }
5398
5399         /* remaining */
5400         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5401         offset += 2;
5402
5403         /* data compaction mode */
5404         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
5405         offset += 2;
5406
5407         /* 2 reserved bytes */
5408         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5409         offset += 2;
5410
5411         /* data len low */
5412         datalen_low = tvb_get_letohs(tvb, offset);
5413         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
5414         offset += 2;
5415
5416         /* data offset */
5417         dataoffset=tvb_get_letohs(tvb, offset);
5418         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5419         offset += 2;
5420
5421         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5422         /* data length high */
5423         datalen_high = tvb_get_letohs(tvb, offset);
5424         proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
5425         offset += 2;
5426
5427         datalen=datalen_high;
5428         datalen=(datalen<<16)|datalen_low;
5429
5430
5431         if (check_col(pinfo->cinfo, COL_INFO))
5432                 col_append_fstr(pinfo->cinfo, COL_INFO,
5433                                 ", %u byte%s", datalen,
5434                                 (datalen == 1) ? "" : "s");
5435
5436
5437         /* 8 reserved bytes */
5438         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
5439         offset += 8;
5440
5441         BYTE_COUNT;
5442
5443         /* file data, might be DCERPC on a pipe */
5444         if(bc){
5445                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5446                     top_tree, offset, bc, datalen, 0, fid);
5447                 bc = 0;
5448         }
5449
5450         END_OF_SMB
5451
5452         /* call AndXCommand (if there are any) */
5453         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5454
5455         return offset;
5456 }
5457
5458 static int
5459 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5460 {
5461         guint32 ofs=0;
5462         guint8  wc, cmd=0xff;
5463         guint16 andxoffset=0, bc, dataoffset=0, datalen_low, datalen_high;
5464         guint32 datalen=0;
5465         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5466         unsigned int fid=0;
5467         guint16 mode = 0;
5468
5469         WORD_COUNT;
5470
5471         /* next smb command */
5472         cmd = tvb_get_guint8(tvb, offset);
5473         if(cmd!=0xff){
5474                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5475         } else {
5476                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5477         }
5478         offset += 1;
5479
5480         /* reserved byte */
5481         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5482         offset += 1;
5483
5484         /* andxoffset */
5485         andxoffset = tvb_get_letohs(tvb, offset);
5486         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5487         offset += 2;
5488
5489         /* fid */
5490         fid = tvb_get_letohs(tvb, offset);
5491         add_fid(tvb, pinfo, tree, offset, 2, fid);
5492         offset += 2;
5493         if (!pinfo->fd->flags.visited) {
5494                 /* remember the FID for the processing of the response */
5495                 si->sip->extra_info=(void *)fid;
5496         }
5497
5498         /* offset */
5499         ofs = tvb_get_letohl(tvb, offset);
5500         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5501         offset += 4;
5502
5503         /* reserved */
5504         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5505         offset += 4;
5506
5507         /* mode */
5508         mode = tvb_get_letohs(tvb, offset);
5509         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
5510
5511         /* remaining */
5512         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5513         offset += 2;
5514
5515         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5516         /* data length high */
5517         datalen_high = tvb_get_letohs(tvb, offset);
5518         proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
5519         offset += 2;
5520
5521         /* data len low */
5522         datalen_low = tvb_get_letohs(tvb, offset);
5523         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
5524         offset += 2;
5525
5526         datalen=datalen_high;
5527         datalen=(datalen<<16)|datalen_low;
5528
5529         /* data offset */
5530         dataoffset=tvb_get_letohs(tvb, offset);
5531         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5532         offset += 2;
5533
5534         /* FIXME: handle Large (48-bit) byte/offset to COL_INFO */
5535         if (check_col(pinfo->cinfo, COL_INFO))
5536                 col_append_fstr(pinfo->cinfo, COL_INFO,
5537                                 ", %u byte%s at offset %u", datalen,
5538                                 (datalen == 1) ? "" : "s", ofs);
5539
5540         if(wc==14){
5541                 /* high offset */
5542                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5543                 offset += 4;
5544         }
5545
5546         BYTE_COUNT;
5547
5548         /* if both the MessageStart and the  WriteRawNamedPipe flags are set
5549            the first two bytes of the payload is the length of the data
5550            also this tells us that this is indeed the IPC$ share
5551            (if we didnt already know that 
5552         */
5553         if((mode&(WRITE_MODE_MESSAGE_START|WRITE_MODE_RAW))==(WRITE_MODE_MESSAGE_START|WRITE_MODE_RAW)){
5554                 proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, TRUE);
5555                 offset += 2;
5556                 dataoffset += 2;
5557                 bc -= 2;
5558                 datalen -= 2;
5559                 if(si->sip){
5560                         si->sip->flags|=SMB_SIF_TID_IS_IPC;
5561                 }
5562         }
5563
5564         /* file data, might be DCERPC on a pipe */
5565         if (bc != 0) {
5566                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5567                     top_tree, offset, bc, datalen, 0, fid);
5568                 bc = 0;
5569         }
5570
5571         END_OF_SMB
5572
5573         /* call AndXCommand (if there are any) */
5574         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5575
5576         return offset;
5577 }
5578
5579 static int
5580 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5581 {
5582         guint8  wc, cmd=0xff;
5583         guint16 andxoffset=0, bc, count_low, count_high;
5584         guint32 count=0;
5585         smb_info_t *si;
5586
5587         WORD_COUNT;
5588
5589         /* next smb command */
5590         cmd = tvb_get_guint8(tvb, offset);
5591         if(cmd!=0xff){
5592                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5593         } else {
5594                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5595         }
5596         offset += 1;
5597
5598         /* reserved byte */
5599         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5600         offset += 1;
5601
5602         /* andxoffset */
5603         andxoffset = tvb_get_letohs(tvb, offset);
5604         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5605         offset += 2;
5606
5607         /* If we have seen the request, then print which FID this refers to */
5608         si = (smb_info_t *)pinfo->private_data;
5609         /* first check if we have seen the request */
5610         if(si->sip != NULL && si->sip->frame_req>0){
5611                 add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
5612         }
5613
5614         /* write count low */
5615         count_low = tvb_get_letohs(tvb, offset);
5616         proto_tree_add_uint(tree, hf_smb_count_low, tvb, offset, 2, count_low);
5617         offset += 2;
5618
5619         /* remaining */
5620         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5621         offset += 2;
5622
5623         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5624         /* write count high */
5625         count_high = tvb_get_letohs(tvb, offset);
5626         proto_tree_add_uint(tree, hf_smb_count_high, tvb, offset, 2, count_high);
5627         offset += 2;
5628
5629         count=count_high;
5630         count=(count<<16)|count_low;
5631
5632         if (check_col(pinfo->cinfo, COL_INFO))
5633                 col_append_fstr(pinfo->cinfo, COL_INFO,
5634                                 ", %u byte%s", count,
5635                                 (count == 1) ? "" : "s");
5636
5637         /* 2 reserved bytes */
5638         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5639         offset += 2;
5640
5641         BYTE_COUNT;
5642
5643         END_OF_SMB
5644
5645         /* call AndXCommand (if there are any) */
5646         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5647
5648         return offset;
5649 }
5650
5651
5652 static const true_false_string tfs_setup_action_guest = {
5653         "Logged in as GUEST",
5654         "Not logged in as GUEST"
5655 };
5656 static int
5657 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5658 {
5659         guint16 mask;
5660         proto_item *item = NULL;
5661         proto_tree *tree = NULL;
5662
5663         mask = tvb_get_letohs(tvb, offset);
5664
5665         if(parent_tree){
5666                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5667                         "Action: 0x%04x", mask);
5668                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
5669         }
5670
5671         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
5672                 tvb, offset, 2, mask);
5673
5674         offset += 2;
5675
5676         return offset;
5677 }
5678
5679
5680 static int
5681 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5682 {
5683         guint8  wc, cmd=0xff;
5684         guint16 bc;
5685         guint16 andxoffset=0;
5686         smb_info_t *si = pinfo->private_data;
5687         int an_len;
5688         const char *an;
5689         int dn_len;
5690         const char *dn;
5691         guint16 pwlen=0;
5692         guint16 sbloblen=0;
5693         guint16 apwlen=0, upwlen=0;
5694
5695         WORD_COUNT;
5696
5697         /* next smb command */
5698         cmd = tvb_get_guint8(tvb, offset);
5699         if(cmd!=0xff){
5700                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5701         } else {
5702                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5703         }
5704         offset += 1;
5705
5706         /* reserved byte */
5707         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5708         offset += 1;
5709
5710         /* andxoffset */
5711         andxoffset = tvb_get_letohs(tvb, offset);
5712         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5713         offset += 2;
5714
5715         /* Maximum Buffer Size */
5716         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
5717         offset += 2;
5718
5719         /* Maximum Multiplex Count */
5720         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
5721         offset += 2;
5722
5723         /* VC Number */
5724         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
5725         offset += 2;
5726
5727         /* session key */
5728         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
5729         offset += 4;
5730
5731         switch (wc) {
5732         case 10:
5733                 /* password length, ASCII*/
5734                 pwlen = tvb_get_letohs(tvb, offset);
5735                 proto_tree_add_uint(tree, hf_smb_password_len,
5736                         tvb, offset, 2, pwlen);
5737                 offset += 2;
5738
5739                 /* 4 reserved bytes */
5740                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5741                 offset += 4;
5742
5743                 break;
5744
5745         case 12:
5746                 /* security blob length */
5747                 sbloblen = tvb_get_letohs(tvb, offset);
5748                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5749                 offset += 2;
5750
5751                 /* 4 reserved bytes */
5752                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5753                 offset += 4;
5754
5755                 /* capabilities */
5756                 dissect_negprot_capabilities(tvb, tree, offset);
5757                 offset += 4;
5758
5759                 break;
5760
5761         case 13:
5762                 /* password length, ANSI*/
5763                 apwlen = tvb_get_letohs(tvb, offset);
5764                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
5765                         tvb, offset, 2, apwlen);
5766                 offset += 2;
5767
5768                 /* password length, Unicode*/
5769                 upwlen = tvb_get_letohs(tvb, offset);
5770                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
5771                         tvb, offset, 2, upwlen);
5772                 offset += 2;
5773
5774                 /* 4 reserved bytes */
5775                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5776                 offset += 4;
5777
5778                 /* capabilities */
5779                 dissect_negprot_capabilities(tvb, tree, offset);
5780                 offset += 4;
5781
5782                 break;
5783         }
5784
5785         BYTE_COUNT;
5786
5787         if (wc==12) {
5788                 proto_item *blob_item;
5789
5790                 /* security blob */
5791
5792                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
5793                                                 tvb, offset, sbloblen, TRUE);
5794
5795                 /* As an optimization, because Windows is perverse,
5796                    we check to see if NTLMSSP is the first part of the 
5797                    blob, and if so, call the NTLMSSP dissector,
5798                    otherwise we call the GSS-API dissector. This is because
5799                    Windows can request RAW NTLMSSP, but will happily handle
5800                    a client that wraps NTLMSSP in SPNEGO
5801                 */
5802
5803                 if(sbloblen){
5804                         tvbuff_t *blob_tvb;
5805                         proto_tree *blob_tree;
5806
5807                         blob_tree = proto_item_add_subtree(blob_item, 
5808                                                            ett_smb_secblob);
5809                         CHECK_BYTE_COUNT(sbloblen);
5810
5811                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
5812                                                   sbloblen);
5813
5814                         if (si && si->ct && si->ct->raw_ntlmssp && 
5815                             !strncmp("NTLMSSP", 
5816                                      tvb_get_ptr(tvb, offset, 7), 7)) {
5817                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
5818                                          blob_tree);
5819
5820                         }
5821                         else {
5822                           call_dissector(gssapi_handle, blob_tvb, 
5823                                          pinfo, blob_tree);
5824                         }
5825
5826                         COUNT_BYTES(sbloblen);
5827                 }
5828
5829                 /* OS */
5830                 an = get_unicode_or_ascii_string(tvb, &offset,
5831                         si->unicode, &an_len, FALSE, FALSE, &bc);
5832                 if (an == NULL)
5833                         goto endofcommand;
5834                 proto_tree_add_string(tree, hf_smb_os, tvb,
5835                         offset, an_len, an);
5836                 COUNT_BYTES(an_len);
5837
5838                 /* LANMAN */
5839                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5840                  * padding/null string/whatever in front of this. W2K doesn't
5841                  * appear to. I suspect that's a bug that got fixed; I also
5842                  * suspect that, in practice, nobody ever looks at that field
5843                  * because the bug didn't appear to get fixed until NT 5.0....
5844                  */
5845                 an = get_unicode_or_ascii_string(tvb, &offset,
5846                         si->unicode, &an_len, FALSE, FALSE, &bc);
5847                 if (an == NULL)
5848                         goto endofcommand;
5849                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5850                         offset, an_len, an);
5851                 COUNT_BYTES(an_len);
5852
5853                 /* Primary domain */
5854                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5855                  * byte in front of this, at least if all the strings are
5856                  * ASCII and the account name is empty. Another bug?
5857                  */
5858                 dn = get_unicode_or_ascii_string(tvb, &offset,
5859                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5860                 if (dn == NULL)
5861                         goto endofcommand;
5862                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5863                         offset, dn_len, dn);
5864                 COUNT_BYTES(dn_len);
5865         } else {
5866                 switch (wc) {
5867
5868                 case 10:
5869                         if(pwlen){
5870                                 /* password, ASCII */
5871                                 CHECK_BYTE_COUNT(pwlen);
5872                                 proto_tree_add_item(tree, hf_smb_password,
5873                                         tvb, offset, pwlen, TRUE);
5874                                 COUNT_BYTES(pwlen);
5875                         }
5876
5877                         break;
5878
5879                 case 13:
5880                         if(apwlen){
5881                                 /* password, ANSI */
5882                                 CHECK_BYTE_COUNT(apwlen);
5883                                 proto_tree_add_item(tree, hf_smb_ansi_password,
5884                                         tvb, offset, apwlen, TRUE);
5885                                 COUNT_BYTES(apwlen);
5886                         }
5887
5888                         if(upwlen){
5889                                 proto_item *item;
5890
5891                                 /* password, Unicode */
5892                                 CHECK_BYTE_COUNT(upwlen);
5893                                 item = proto_tree_add_item(tree, hf_smb_unicode_password,
5894                                         tvb, offset, upwlen, TRUE);
5895
5896                                 if (upwlen > 24) {
5897                                         proto_tree *subtree;
5898
5899                                         subtree = proto_item_add_subtree(item, ett_smb_unicode_password);
5900
5901                                         dissect_ntlmv2_response(
5902                                                 tvb, subtree, offset, upwlen);
5903                                 }
5904
5905                                 COUNT_BYTES(upwlen);
5906                         }
5907
5908                         break;
5909                 }
5910
5911                 /* Account Name */
5912                 an = get_unicode_or_ascii_string(tvb, &offset,
5913                         si->unicode, &an_len, FALSE, FALSE, &bc);
5914                 if (an == NULL)
5915                         goto endofcommand;
5916                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
5917                         an);
5918                 COUNT_BYTES(an_len);
5919
5920                 /* Primary domain */
5921                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5922                  * byte in front of this, at least if all the strings are
5923                  * ASCII and the account name is empty. Another bug?
5924                  */
5925                 dn = get_unicode_or_ascii_string(tvb, &offset,
5926                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5927                 if (dn == NULL)
5928                         goto endofcommand;
5929                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5930                         offset, dn_len, dn);
5931                 COUNT_BYTES(dn_len);
5932
5933                 if (check_col(pinfo->cinfo, COL_INFO)) {
5934                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
5935
5936                         if (!dn[0] && !an[0])
5937                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5938                                                 "anonymous");
5939                         else
5940                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5941                                                 "%s\\%s", dn,an);
5942                 }
5943
5944                 /* OS */
5945                 an = get_unicode_or_ascii_string(tvb, &offset,
5946                         si->unicode, &an_len, FALSE, FALSE, &bc);
5947                 if (an == NULL)
5948                         goto endofcommand;
5949                 proto_tree_add_string(tree, hf_smb_os, tvb,
5950                         offset, an_len, an);
5951                 COUNT_BYTES(an_len);
5952
5953                 /* LANMAN */
5954                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5955                  * padding/null string/whatever in front of this. W2K doesn't
5956                  * appear to. I suspect that's a bug that got fixed; I also
5957                  * suspect that, in practice, nobody ever looks at that field
5958                  * because the bug didn't appear to get fixed until NT 5.0....
5959                  */
5960                 an = get_unicode_or_ascii_string(tvb, &offset,
5961                         si->unicode, &an_len, FALSE, FALSE, &bc);
5962                 if (an == NULL)
5963                         goto endofcommand;
5964                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5965                         offset, an_len, an);
5966                 COUNT_BYTES(an_len);
5967         }
5968
5969         END_OF_SMB
5970
5971         /* call AndXCommand (if there are any) */
5972         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5973
5974         return offset;
5975 }
5976
5977 static int
5978 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5979 {
5980         guint8  wc, cmd=0xff;
5981         guint16 andxoffset=0, bc;
5982         guint16 sbloblen=0;
5983         smb_info_t *si = pinfo->private_data;
5984         int an_len;
5985         const char *an;
5986
5987         WORD_COUNT;
5988
5989         /* next smb command */
5990         cmd = tvb_get_guint8(tvb, offset);
5991         if(cmd!=0xff){
5992                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5993         } else {
5994                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5995         }
5996         offset += 1;
5997
5998         /* reserved byte */
5999         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6000         offset += 1;
6001
6002         /* andxoffset */
6003         andxoffset = tvb_get_letohs(tvb, offset);
6004         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6005         offset += 2;
6006
6007         /* flags */
6008         offset = dissect_setup_action(tvb, tree, offset);
6009
6010         if(wc==4){
6011                 /* security blob length */
6012                 sbloblen = tvb_get_letohs(tvb, offset);
6013                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
6014                 offset += 2;
6015         }
6016
6017         BYTE_COUNT;
6018
6019         if(wc==4) {
6020                 proto_item *blob_item;
6021
6022                 /* security blob */
6023
6024                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
6025                                                 tvb, offset, sbloblen, TRUE);
6026
6027                 if(sbloblen){
6028                         tvbuff_t *blob_tvb;
6029                         proto_tree *blob_tree;
6030
6031                         blob_tree = proto_item_add_subtree(blob_item, 
6032                                                            ett_smb_secblob);
6033                         CHECK_BYTE_COUNT(sbloblen);
6034
6035                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
6036                                                     sbloblen);
6037
6038                         if (si && si->ct && si->ct->raw_ntlmssp && 
6039                             !strncmp("NTLMSSP", 
6040                                      tvb_get_ptr(tvb, offset, 7), 7)) {
6041                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
6042                                          blob_tree);
6043
6044                         }
6045                         else {
6046                           call_dissector(gssapi_handle, blob_tvb, pinfo, 
6047                                          blob_tree);
6048
6049                         }
6050
6051                         COUNT_BYTES(sbloblen);
6052                 }
6053         }
6054
6055         /* OS */
6056         an = get_unicode_or_ascii_string(tvb, &offset,
6057                 si->unicode, &an_len, FALSE, FALSE, &bc);
6058         if (an == NULL)
6059                 goto endofcommand;
6060         proto_tree_add_string(tree, hf_smb_os, tvb,
6061                 offset, an_len, an);
6062         COUNT_BYTES(an_len);
6063
6064         /* LANMAN */
6065         an = get_unicode_or_ascii_string(tvb, &offset,
6066                 si->unicode, &an_len, FALSE, FALSE, &bc);
6067         if (an == NULL)
6068                 goto endofcommand;
6069         proto_tree_add_string(tree, hf_smb_lanman, tvb,
6070                 offset, an_len, an);
6071         COUNT_BYTES(an_len);
6072
6073         if(wc==3) {
6074                 /* Primary domain */
6075                 an = get_unicode_or_ascii_string(tvb, &offset,
6076                         si->unicode, &an_len, FALSE, FALSE, &bc);
6077                 if (an == NULL)
6078                         goto endofcommand;
6079                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
6080                         offset, an_len, an);
6081                 COUNT_BYTES(an_len);
6082         }
6083
6084         END_OF_SMB
6085
6086         /* call AndXCommand (if there are any) */
6087         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6088
6089         return offset;
6090 }
6091
6092
6093 static int
6094 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6095 {
6096         guint8  wc, cmd=0xff;
6097         guint16 andxoffset=0;
6098         guint16 bc;
6099
6100         WORD_COUNT;
6101
6102         /* next smb command */
6103         cmd = tvb_get_guint8(tvb, offset);
6104         if(cmd!=0xff){
6105                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6106         } else {
6107                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6108         }
6109         offset += 1;
6110
6111         /* reserved byte */
6112         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6113         offset += 1;
6114
6115         /* andxoffset */
6116         andxoffset = tvb_get_letohs(tvb, offset);
6117         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6118         offset += 2;
6119
6120         BYTE_COUNT;
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 const true_false_string tfs_connect_support_search = {
6132         "Exclusive search bits supported",
6133         "Exclusive search bits not supported"
6134 };
6135 static const true_false_string tfs_connect_support_in_dfs = {
6136         "Share is in Dfs",
6137         "Share isn't in Dfs"
6138 };
6139
6140 static int
6141 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6142 {
6143         guint16 mask;
6144         proto_item *item = NULL;
6145         proto_tree *tree = NULL;
6146
6147         mask = tvb_get_letohs(tvb, offset);
6148
6149         if(parent_tree){
6150                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6151                         "Optional Support: 0x%04x", mask);
6152                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
6153         }
6154
6155         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
6156                 tvb, offset, 2, mask);
6157         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
6158                 tvb, offset, 2, mask);
6159
6160         offset += 2;
6161
6162         return offset;
6163 }
6164
6165 static const true_false_string tfs_disconnect_tid = {
6166         "DISCONNECT TID",
6167         "Do NOT disconnect TID"
6168 };
6169
6170 static int
6171 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6172 {
6173         guint16 mask;
6174         proto_item *item = NULL;
6175         proto_tree *tree = NULL;
6176
6177         mask = tvb_get_letohs(tvb, offset);
6178
6179         if(parent_tree){
6180                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6181                         "Flags: 0x%04x", mask);
6182                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
6183         }
6184
6185         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
6186                 tvb, offset, 2, mask);
6187
6188         offset += 2;
6189
6190         return offset;
6191 }
6192
6193 static int
6194 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6195 {
6196         guint8  wc, cmd=0xff;
6197         guint16 bc;
6198         guint16 andxoffset=0, pwlen=0;
6199         smb_info_t *si = pinfo->private_data;
6200         int an_len;
6201         const char *an;
6202
6203         WORD_COUNT;
6204
6205         /* next smb command */
6206         cmd = tvb_get_guint8(tvb, offset);
6207         if(cmd!=0xff){
6208                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6209         } else {
6210                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6211         }
6212         offset += 1;
6213
6214         /* reserved byte */
6215         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6216         offset += 1;
6217
6218         /* andxoffset */
6219         andxoffset = tvb_get_letohs(tvb, offset);
6220         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6221         offset += 2;
6222
6223         /* flags */
6224         offset = dissect_connect_flags(tvb, tree, offset);
6225
6226         /* password length*/
6227         pwlen = tvb_get_letohs(tvb, offset);
6228         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
6229         offset += 2;
6230
6231         BYTE_COUNT;
6232
6233         /* password */
6234         CHECK_BYTE_COUNT(pwlen);
6235         proto_tree_add_item(tree, hf_smb_password,
6236                 tvb, offset, pwlen, TRUE);
6237         COUNT_BYTES(pwlen);
6238
6239         /* Path */
6240         an = get_unicode_or_ascii_string(tvb, &offset,
6241                 si->unicode, &an_len, FALSE, FALSE, &bc);
6242         if (an == NULL)
6243                 goto endofcommand;
6244         proto_tree_add_string(tree, hf_smb_path, tvb,
6245                 offset, an_len, an);
6246         COUNT_BYTES(an_len);
6247
6248         if (check_col(pinfo->cinfo, COL_INFO)) {
6249                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
6250         }
6251
6252         /*
6253          * NOTE: the Service string is always ASCII, even if the
6254          * "strings are Unicode" bit is set in the flags2 field
6255          * of the SMB.
6256          */
6257
6258         /* Service */
6259         /* XXX - what if this runs past bc? */
6260         an_len = tvb_strsize(tvb, offset);
6261         CHECK_BYTE_COUNT(an_len);
6262         an = tvb_get_ptr(tvb, offset, an_len);
6263         proto_tree_add_string(tree, hf_smb_service, tvb,
6264                 offset, an_len, an);
6265         COUNT_BYTES(an_len);
6266
6267         END_OF_SMB
6268
6269         /* call AndXCommand (if there are any) */
6270         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6271
6272         return offset;
6273 }
6274
6275
6276 static int
6277 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6278 {
6279         guint8  wc, wleft, cmd=0xff;
6280         guint16 andxoffset=0;
6281         guint16 bc;
6282         int an_len;
6283         const char *an;
6284         smb_info_t *si = pinfo->private_data;
6285
6286         WORD_COUNT;
6287
6288         wleft = wc;     /* this is at least 1 */
6289
6290         /* next smb command */
6291         cmd = tvb_get_guint8(tvb, offset);
6292         if(cmd!=0xff){
6293                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6294         } else {
6295                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6296         }
6297         offset += 1;
6298
6299         /* reserved byte */
6300         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6301         offset += 1;
6302
6303         wleft--;
6304         if (wleft == 0)
6305                 goto bytecount;
6306
6307         /* andxoffset */
6308         andxoffset = tvb_get_letohs(tvb, offset);
6309         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6310         offset += 2;
6311         wleft--;
6312         if (wleft == 0)
6313                 goto bytecount;
6314
6315         /* flags */
6316         offset = dissect_connect_support_bits(tvb, tree, offset);
6317         wleft--;
6318
6319         /* XXX - I've seen captures where this is 7, but I have no
6320            idea how to dissect it.  I'm guessing the third word
6321            contains connect support bits, which looks plausible
6322            from the values I've seen. */
6323
6324         while (wleft != 0) {
6325                 proto_tree_add_text(tree, tvb, offset, 2,
6326                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
6327                 offset += 2;
6328                 wleft--;
6329         }
6330
6331         BYTE_COUNT;
6332
6333         /*
6334          * NOTE: even though the SNIA CIFS spec doesn't say there's
6335          * a "Service" string if there's a word count of 2, the
6336          * document at
6337          *
6338          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
6339          *
6340          * (it's in an ugly format - text intended to be sent to a
6341          * printer, with backspaces and overstrikes used for boldfacing
6342          * and underlining; UNIX "col -b" can be used to strip the
6343          * overstrikes out) says there's a "Service" string there, and
6344          * some network traffic has it.
6345          */
6346
6347         /*
6348          * NOTE: the Service string is always ASCII, even if the
6349          * "strings are Unicode" bit is set in the flags2 field
6350          * of the SMB.
6351          */
6352
6353         /* Service */
6354         /* XXX - what if this runs past bc? */
6355         an_len = tvb_strsize(tvb, offset);
6356         CHECK_BYTE_COUNT(an_len);
6357         an = tvb_get_ptr(tvb, offset, an_len);
6358         proto_tree_add_string(tree, hf_smb_service, tvb,
6359                 offset, an_len, an);
6360         COUNT_BYTES(an_len);
6361
6362         /* Now when we know the service type, store it so that we know it for later commands down
6363            this tree */
6364         if(!pinfo->fd->flags.visited){
6365                 /* Remove any previous entry for this TID */
6366                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
6367                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
6368                 }
6369                 if(strcmp(an,"IPC") == 0){
6370                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
6371                 } else {
6372                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
6373                 }
6374         }
6375
6376
6377         if(wc==3){
6378                 if (bc != 0) {
6379                         /*
6380                          * Sometimes this isn't present.
6381                          */
6382
6383                         /* Native FS */
6384                         an = get_unicode_or_ascii_string(tvb, &offset,
6385                                 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
6386                                 &bc);
6387                         if (an == NULL)
6388                                 goto endofcommand;
6389                         proto_tree_add_string(tree, hf_smb_fs, tvb,
6390                                 offset, an_len, an);
6391                         COUNT_BYTES(an_len);
6392                 }
6393         }
6394
6395         END_OF_SMB
6396
6397         /* call AndXCommand (if there are any) */
6398         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6399
6400         return offset;
6401 }
6402
6403
6404
6405 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6406    NT Transaction command  begins here
6407    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
6408 #define NT_TRANS_CREATE         1
6409 #define NT_TRANS_IOCTL          2
6410 #define NT_TRANS_SSD            3
6411 #define NT_TRANS_NOTIFY         4
6412 #define NT_TRANS_RENAME         5
6413 #define NT_TRANS_QSD            6
6414 #define NT_TRANS_GET_USER_QUOTA 7
6415 #define NT_TRANS_SET_USER_QUOTA 8
6416 const value_string nt_cmd_vals[] = {
6417         {NT_TRANS_CREATE,               "NT CREATE"},
6418         {NT_TRANS_IOCTL,                "NT IOCTL"},
6419         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
6420         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
6421         {NT_TRANS_RENAME,               "NT RENAME"},
6422         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
6423         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
6424         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
6425         {0, NULL}
6426 };
6427
6428 static const value_string nt_ioctl_isfsctl_vals[] = {
6429         {0,     "Device IOCTL"},
6430         {1,     "FS control : FSCTL"},
6431         {0, NULL}
6432 };
6433
6434 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
6435 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
6436         "Apply the command to share root handle (MUST BE Dfs)",
6437         "Apply to this share",
6438 };
6439
6440 static const value_string nt_notify_action_vals[] = {
6441         {1,     "ADDED (object was added"},
6442         {2,     "REMOVED (object was removed)"},
6443         {3,     "MODIFIED (object was modified)"},
6444         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
6445         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
6446         {6,     "ADDED_STREAM (a stream was added)"},
6447         {7,     "REMOVED_STREAM (a stream was removed)"},
6448         {8,     "MODIFIED_STREAM (a stream was modified)"},
6449         {0, NULL}
6450 };
6451
6452 static const value_string watch_tree_vals[] = {
6453         {0,     "Current directory only"},
6454         {1,     "Subdirectories also"},
6455         {0, NULL}
6456 };
6457
6458 #define NT_NOTIFY_STREAM_WRITE  0x00000800
6459 #define NT_NOTIFY_STREAM_SIZE   0x00000400
6460 #define NT_NOTIFY_STREAM_NAME   0x00000200
6461 #define NT_NOTIFY_SECURITY      0x00000100
6462 #define NT_NOTIFY_EA            0x00000080
6463 #define NT_NOTIFY_CREATION      0x00000040
6464 #define NT_NOTIFY_LAST_ACCESS   0x00000020
6465 #define NT_NOTIFY_LAST_WRITE    0x00000010
6466 #define NT_NOTIFY_SIZE          0x00000008
6467 #define NT_NOTIFY_ATTRIBUTES    0x00000004
6468 #define NT_NOTIFY_DIR_NAME      0x00000002
6469 #define NT_NOTIFY_FILE_NAME     0x00000001
6470 static const true_false_string tfs_nt_notify_stream_write = {
6471         "Notify on changes to STREAM WRITE",
6472         "Do NOT notify on changes to stream write",
6473 };
6474 static const true_false_string tfs_nt_notify_stream_size = {
6475         "Notify on changes to STREAM SIZE",
6476         "Do NOT notify on changes to stream size",
6477 };
6478 static const true_false_string tfs_nt_notify_stream_name = {
6479         "Notify on changes to STREAM NAME",
6480         "Do NOT notify on changes to stream name",
6481 };
6482 static const true_false_string tfs_nt_notify_security = {
6483         "Notify on changes to SECURITY",
6484         "Do NOT notify on changes to security",
6485 };
6486 static const true_false_string tfs_nt_notify_ea = {
6487         "Notify on changes to EA",
6488         "Do NOT notify on changes to EA",
6489 };
6490 static const true_false_string tfs_nt_notify_creation = {
6491         "Notify on changes to CREATION TIME",
6492         "Do NOT notify on changes to creation time",
6493 };
6494 static const true_false_string tfs_nt_notify_last_access = {
6495         "Notify on changes to LAST ACCESS TIME",
6496         "Do NOT notify on changes to last access time",
6497 };
6498 static const true_false_string tfs_nt_notify_last_write = {
6499         "Notify on changes to LAST WRITE TIME",
6500         "Do NOT notify on changes to last write time",
6501 };
6502 static const true_false_string tfs_nt_notify_size = {
6503         "Notify on changes to SIZE",
6504         "Do NOT notify on changes to size",
6505 };
6506 static const true_false_string tfs_nt_notify_attributes = {
6507         "Notify on changes to ATTRIBUTES",
6508         "Do NOT notify on changes to attributes",
6509 };
6510 static const true_false_string tfs_nt_notify_dir_name = {
6511         "Notify on changes to DIR NAME",
6512         "Do NOT notify on changes to dir name",
6513 };
6514 static const true_false_string tfs_nt_notify_file_name = {
6515         "Notify on changes to FILE NAME",
6516         "Do NOT notify on changes to file name",
6517 };
6518
6519 static const value_string create_disposition_vals[] = {
6520         {0,     "Supersede (supersede existing file (if it exists))"},
6521         {1,     "Open (if file exists open it, else fail)"},
6522         {2,     "Create (if file exists fail, else create it)"},
6523         {3,     "Open If (if file exists open it, else create it)"},
6524         {4,     "Overwrite (if file exists overwrite, else fail)"},
6525         {5,     "Overwrite If (if file exists overwrite, else create it)"},
6526         {0, NULL}
6527 };
6528
6529 static const value_string impersonation_level_vals[] = {
6530         {0,     "Anonymous"},
6531         {1,     "Identification"},
6532         {2,     "Impersonation"},
6533         {3,     "Delegation"},
6534         {0, NULL}
6535 };
6536
6537 static const true_false_string tfs_nt_security_flags_context_tracking = {
6538         "Security tracking mode is DYNAMIC",
6539         "Security tracking mode is STATIC",
6540 };
6541
6542 static const true_false_string tfs_nt_security_flags_effective_only = {
6543         "ONLY ENABLED aspects of the client's security context are available",
6544         "ALL aspects of the client's security context are available",
6545 };
6546
6547 static const true_false_string tfs_nt_create_bits_oplock = {
6548         "Requesting OPLOCK",
6549         "Does NOT request oplock"
6550 };
6551
6552 static const true_false_string tfs_nt_create_bits_boplock = {
6553         "Requesting BATCH OPLOCK",
6554         "Does NOT request batch oplock"
6555 };
6556
6557 /*
6558  * XXX - must be a directory, and can be a file, or can be a directory,
6559  * and must be a file?
6560  */
6561 static const true_false_string tfs_nt_create_bits_dir = {
6562         "Target of open MUST be a DIRECTORY",
6563         "Target of open can be a file"
6564 };
6565
6566 static const true_false_string tfs_nt_create_bits_ext_resp = {
6567   "Extended responses required",
6568   "Extended responses NOT required"
6569 };
6570
6571 static const true_false_string tfs_nt_access_mask_generic_read = {
6572         "GENERIC READ is set",
6573         "Generic read is NOT set"
6574 };
6575 static const true_false_string tfs_nt_access_mask_generic_write = {
6576         "GENERIC WRITE is set",
6577         "Generic write is NOT set"
6578 };
6579 static const true_false_string tfs_nt_access_mask_generic_execute = {
6580         "GENERIC EXECUTE is set",
6581         "Generic execute is NOT set"
6582 };
6583 static const true_false_string tfs_nt_access_mask_generic_all = {
6584         "GENERIC ALL is set",
6585         "Generic all is NOT set"
6586 };
6587 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
6588         "MAXIMUM ALLOWED is set",
6589         "Maximum allowed is NOT set"
6590 };
6591 static const true_false_string tfs_nt_access_mask_system_security = {
6592         "SYSTEM SECURITY is set",
6593         "System security is NOT set"
6594 };
6595 static const true_false_string tfs_nt_access_mask_synchronize = {
6596         "Can wait on handle to SYNCHRONIZE on completion of I/O",
6597         "Can NOT wait on handle to synchronize on completion of I/O"
6598 };
6599 static const true_false_string tfs_nt_access_mask_write_owner = {
6600         "Can WRITE OWNER (take ownership)",
6601         "Can NOT write owner (take ownership)"
6602 };
6603 static const true_false_string tfs_nt_access_mask_write_dac = {
6604         "OWNER may WRITE the DAC",
6605         "Owner may NOT write to the DAC"
6606 };
6607 static const true_false_string tfs_nt_access_mask_read_control = {
6608         "READ ACCESS to owner, group and ACL of the SID",
6609         "Read access is NOT granted to owner, group and ACL of the SID"
6610 };
6611 static const true_false_string tfs_nt_access_mask_delete = {
6612         "DELETE access",
6613         "NO delete access"
6614 };
6615 static const true_false_string tfs_nt_access_mask_write_attributes = {
6616         "WRITE ATTRIBUTES access",
6617         "NO write attributes access"
6618 };
6619 static const true_false_string tfs_nt_access_mask_read_attributes = {
6620         "READ ATTRIBUTES access",
6621         "NO read attributes access"
6622 };
6623 static const true_false_string tfs_nt_access_mask_delete_child = {
6624         "DELETE CHILD access",
6625         "NO delete child access"
6626 };
6627 static const true_false_string tfs_nt_access_mask_execute = {
6628         "EXECUTE access",
6629         "NO execute access"
6630 };
6631 static const true_false_string tfs_nt_access_mask_write_ea = {
6632         "WRITE EXTENDED ATTRIBUTES access",
6633         "NO write extended attributes access"
6634 };
6635 static const true_false_string tfs_nt_access_mask_read_ea = {
6636         "READ EXTENDED ATTRIBUTES access",
6637         "NO read extended attributes access"
6638 };
6639 static const true_false_string tfs_nt_access_mask_append = {
6640         "APPEND access",
6641         "NO append access"
6642 };
6643 static const true_false_string tfs_nt_access_mask_write = {
6644         "WRITE access",
6645         "NO write access"
6646 };
6647 static const true_false_string tfs_nt_access_mask_read = {
6648         "READ access",
6649         "NO read access"
6650 };
6651
6652 static const true_false_string tfs_nt_share_access_delete = {
6653         "Object can be shared for DELETE",
6654         "Object can NOT be shared for delete"
6655 };
6656 static const true_false_string tfs_nt_share_access_write = {
6657         "Object can be shared for WRITE",
6658         "Object can NOT be shared for write"
6659 };
6660 static const true_false_string tfs_nt_share_access_read = {
6661         "Object can be shared for READ",
6662         "Object can NOT be shared for read"
6663 };
6664
6665 static const value_string oplock_level_vals[] = {
6666         {0,     "No oplock granted"},
6667         {1,     "Exclusive oplock granted"},
6668         {2,     "Batch oplock granted"},
6669         {3,     "Level II oplock granted"},
6670         {0, NULL}
6671 };
6672
6673 static const value_string device_type_vals[] = {
6674         {0x00000001,    "Beep"},
6675         {0x00000002,    "CDROM"},
6676         {0x00000003,    "CDROM Filesystem"},
6677         {0x00000004,    "Controller"},
6678         {0x00000005,    "Datalink"},
6679         {0x00000006,    "Dfs"},
6680         {0x00000007,    "Disk"},
6681         {0x00000008,    "Disk Filesystem"},
6682         {0x00000009,    "Filesystem"},
6683         {0x0000000a,    "Inport Port"},
6684         {0x0000000b,    "Keyboard"},
6685         {0x0000000c,    "Mailslot"},
6686         {0x0000000d,    "MIDI-In"},
6687         {0x0000000e,    "MIDI-Out"},
6688         {0x0000000f,    "Mouse"},
6689         {0x00000010,    "Multi UNC Provider"},
6690         {0x00000011,    "Named Pipe"},
6691         {0x00000012,    "Network"},
6692         {0x00000013,    "Network Browser"},
6693         {0x00000014,    "Network Filesystem"},
6694         {0x00000015,    "NULL"},
6695         {0x00000016,    "Parallel Port"},
6696         {0x00000017,    "Physical card"},
6697         {0x00000018,    "Printer"},
6698         {0x00000019,    "Scanner"},
6699         {0x0000001a,    "Serial Mouse port"},
6700         {0x0000001b,    "Serial port"},
6701         {0x0000001c,    "Screen"},
6702         {0x0000001d,    "Sound"},
6703         {0x0000001e,    "Streams"},
6704         {0x0000001f,    "Tape"},
6705         {0x00000020,    "Tape Filesystem"},
6706         {0x00000021,    "Transport"},
6707         {0x00000022,    "Unknown"},
6708         {0x00000023,    "Video"},
6709         {0x00000024,    "Virtual Disk"},
6710         {0x00000025,    "WAVE-In"},
6711         {0x00000026,    "WAVE-Out"},
6712         {0x00000027,    "8042 Port"},
6713         {0x00000028,    "Network Redirector"},
6714         {0x00000029,    "Battery"},
6715         {0x0000002a,    "Bus Extender"},
6716         {0x0000002b,    "Modem"},
6717         {0x0000002c,    "VDM"},
6718         {0,     NULL}
6719 };
6720
6721 static const value_string is_directory_vals[] = {
6722         {0,     "This is NOT a directory"},
6723         {1,     "This is a DIRECTORY"},
6724         {0, NULL}
6725 };
6726
6727 typedef struct _nt_trans_data {
6728         int subcmd;
6729         guint32 sd_len;
6730         guint32 ea_len;
6731 } nt_trans_data;
6732
6733
6734
6735 static int
6736 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6737 {
6738         guint8 mask;
6739         proto_item *item = NULL;
6740         proto_tree *tree = NULL;
6741
6742         mask = tvb_get_guint8(tvb, offset);
6743
6744         if(parent_tree){
6745                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6746                         "Security Flags: 0x%02x", mask);
6747                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
6748         }
6749
6750         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
6751                 tvb, offset, 1, mask);
6752         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
6753                 tvb, offset, 1, mask);
6754
6755         offset += 1;
6756
6757         return offset;
6758 }
6759
6760 static int
6761 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6762 {
6763         guint32 mask;
6764         proto_item *item = NULL;
6765         proto_tree *tree = NULL;
6766
6767         mask = tvb_get_letohl(tvb, offset);
6768
6769         if(parent_tree){
6770                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6771                         "Share Access: 0x%08x", mask);
6772                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
6773         }
6774
6775         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
6776                 tvb, offset, 4, mask);
6777         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
6778                 tvb, offset, 4, mask);
6779         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
6780                 tvb, offset, 4, mask);
6781
6782         offset += 4;
6783
6784         return offset;
6785 }
6786
6787 /* FIXME: need to call dissect_nt_access_mask() instead */
6788
6789 static int
6790 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6791 {
6792         guint32 mask;
6793         proto_item *item = NULL;
6794         proto_tree *tree = NULL;
6795
6796         mask = tvb_get_letohl(tvb, offset);
6797
6798         if(parent_tree){
6799                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6800                         "Access Mask: 0x%08x", mask);
6801                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
6802         }
6803
6804         /*
6805          * Some of these bits come from
6806          *
6807          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6808          *
6809          * and others come from the section on ZwOpenFile in "Windows(R)
6810          * NT(R)/2000 Native API Reference".
6811          */
6812         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
6813                 tvb, offset, 4, mask);
6814         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
6815                 tvb, offset, 4, mask);
6816         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
6817                 tvb, offset, 4, mask);
6818         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
6819                 tvb, offset, 4, mask);
6820         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
6821                 tvb, offset, 4, mask);
6822         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
6823                 tvb, offset, 4, mask);
6824         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
6825                 tvb, offset, 4, mask);
6826         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
6827                 tvb, offset, 4, mask);
6828         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
6829                 tvb, offset, 4, mask);
6830         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
6831                 tvb, offset, 4, mask);
6832         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
6833                 tvb, offset, 4, mask);
6834         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
6835                 tvb, offset, 4, mask);
6836         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
6837                 tvb, offset, 4, mask);
6838         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
6839                 tvb, offset, 4, mask);
6840         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
6841                 tvb, offset, 4, mask);
6842         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
6843                 tvb, offset, 4, mask);
6844         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
6845                 tvb, offset, 4, mask);
6846         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
6847                 tvb, offset, 4, mask);
6848         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
6849                 tvb, offset, 4, mask);
6850         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
6851                 tvb, offset, 4, mask);
6852
6853         offset += 4;
6854
6855         return offset;
6856 }
6857
6858 static int
6859 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6860 {
6861         guint32 mask;
6862         proto_item *item = NULL;
6863         proto_tree *tree = NULL;
6864
6865         mask = tvb_get_letohl(tvb, offset);
6866
6867         if(parent_tree){
6868                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6869                         "Create Flags: 0x%08x", mask);
6870                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
6871         }
6872
6873         /*
6874          * XXX - it's 0x00000016 in at least one capture, but
6875          * Network Monitor doesn't say what the 0x00000010 bit is.
6876          * Does the Win32 API documentation, or NT Native API book,
6877          * suggest anything?
6878          *
6879          * That is the extended response desired bit ... RJS, from Samba
6880          * Well, maybe. Samba thinks it is, and uses it to encode
6881          * OpLock granted as the high order bit of the Action field
6882          * in the response. However, Windows does not do that. Or at least
6883          * Win2K doesn't.
6884          */
6885         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
6886                                tvb, offset, 4, mask);
6887         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
6888                 tvb, offset, 4, mask);
6889         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
6890                 tvb, offset, 4, mask);
6891         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
6892                 tvb, offset, 4, mask);
6893
6894         offset += 4;
6895
6896         return offset;
6897 }
6898
6899 /*
6900  * XXX - there are some more flags in the description of "ZwOpenFile()"
6901  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
6902  * the wire as well?  (The spec at
6903  *
6904  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6905  *
6906  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
6907  * via the SMB protocol.  The NT redirector should convert this option
6908  * to FILE_WRITE_THROUGH."
6909  *
6910  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
6911  * values one would infer from their position in the list of flags for
6912  * "ZwOpenFile()".  Most of the others probably have those values
6913  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
6914  * which might go over the wire (for the benefit of backup/restore software).
6915  */
6916 static const true_false_string tfs_nt_create_options_directory = {
6917         "File being created/opened must be a directory",
6918         "File being created/opened must not be a directory"
6919 };
6920 static const true_false_string tfs_nt_create_options_write_through = {
6921         "Writes should flush buffered data before completing",
6922         "Writes need not flush buffered data before completing"
6923 };
6924 static const true_false_string tfs_nt_create_options_sequential_only = {
6925         "The file will only be accessed sequentially",
6926         "The file might not only be accessed sequentially"
6927 };
6928 static const true_false_string tfs_nt_create_options_sync_io_alert = {
6929         "All operations SYNCHRONOUS, waits subject to termination from alert",
6930         "Operations NOT necessarily synchronous"
6931 };
6932 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
6933         "All operations SYNCHRONOUS, waits not subject to alert",
6934         "Operations NOT necessarily synchronous"
6935 };
6936 static const true_false_string tfs_nt_create_options_non_directory = {
6937         "File being created/opened must not be a directory",
6938         "File being created/opened must be a directory"
6939 };
6940 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
6941         "The client does not understand extended attributes",
6942         "The client understands extended attributes"
6943 };
6944 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
6945         "The client understands only 8.3 file names",
6946         "The client understands long file names"
6947 };
6948 static const true_false_string tfs_nt_create_options_random_access = {
6949         "The file will be accessed randomly",
6950         "The file will not be accessed randomly"
6951 };
6952 static const true_false_string tfs_nt_create_options_delete_on_close = {
6953         "The file should be deleted when it is closed",
6954         "The file should not be deleted when it is closed"
6955 };
6956
6957 static int
6958 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6959 {
6960         guint32 mask;
6961         proto_item *item = NULL;
6962         proto_tree *tree = NULL;
6963
6964         mask = tvb_get_letohl(tvb, offset);
6965
6966         if(parent_tree){
6967                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6968                         "Create Options: 0x%08x", mask);
6969                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
6970         }
6971
6972         /*
6973          * From
6974          *
6975          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6976          */
6977         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
6978                 tvb, offset, 4, mask);
6979         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
6980                 tvb, offset, 4, mask);
6981         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
6982                 tvb, offset, 4, mask);
6983         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
6984                 tvb, offset, 4, mask);
6985         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
6986                 tvb, offset, 4, mask);
6987         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
6988                 tvb, offset, 4, mask);
6989         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
6990                 tvb, offset, 4, mask);
6991         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
6992                 tvb, offset, 4, mask);
6993         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
6994                 tvb, offset, 4, mask);
6995         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
6996                 tvb, offset, 4, mask);
6997
6998         offset += 4;
6999
7000         return offset;
7001 }
7002
7003 static int
7004 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7005 {
7006         guint32 mask;
7007         proto_item *item = NULL;
7008         proto_tree *tree = NULL;
7009
7010         mask = tvb_get_letohl(tvb, offset);
7011
7012         if(parent_tree){
7013                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7014                         "Completion Filter: 0x%08x", mask);
7015                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
7016         }
7017
7018         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
7019                 tvb, offset, 4, mask);
7020         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
7021                 tvb, offset, 4, mask);
7022         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
7023                 tvb, offset, 4, mask);
7024         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
7025                 tvb, offset, 4, mask);
7026         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
7027                 tvb, offset, 4, mask);
7028         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
7029                 tvb, offset, 4, mask);
7030         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
7031                 tvb, offset, 4, mask);
7032         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
7033                 tvb, offset, 4, mask);
7034         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
7035                 tvb, offset, 4, mask);
7036         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
7037                 tvb, offset, 4, mask);
7038         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
7039                 tvb, offset, 4, mask);
7040         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
7041                 tvb, offset, 4, mask);
7042
7043         offset += 4;
7044         return offset;
7045 }
7046
7047 static int
7048 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7049 {
7050         guint8 mask;
7051         proto_item *item = NULL;
7052         proto_tree *tree = NULL;
7053
7054         mask = tvb_get_guint8(tvb, offset);
7055
7056         if(parent_tree){
7057                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7058                         "Completion Filter: 0x%02x", mask);
7059                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
7060         }
7061
7062         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
7063                 tvb, offset, 1, mask);
7064
7065         offset += 1;
7066         return offset;
7067 }
7068
7069 /*
7070  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
7071  * Native API Reference".
7072  */
7073 static const true_false_string tfs_nt_qsd_owner = {
7074         "Requesting OWNER security information",
7075         "NOT requesting owner security information",
7076 };
7077
7078 static const true_false_string tfs_nt_qsd_group = {
7079         "Requesting GROUP security information",
7080         "NOT requesting group security information",
7081 };
7082
7083 static const true_false_string tfs_nt_qsd_dacl = {
7084         "Requesting DACL security information",
7085         "NOT requesting DACL security information",
7086 };
7087
7088 static const true_false_string tfs_nt_qsd_sacl = {
7089         "Requesting SACL security information",
7090         "NOT requesting SACL security information",
7091 };
7092
7093 #define NT_QSD_OWNER    0x00000001
7094 #define NT_QSD_GROUP    0x00000002
7095 #define NT_QSD_DACL     0x00000004
7096 #define NT_QSD_SACL     0x00000008
7097
7098 static int
7099 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7100 {
7101         guint32 mask;
7102         proto_item *item = NULL;
7103         proto_tree *tree = NULL;
7104
7105         mask = tvb_get_letohl(tvb, offset);
7106
7107         if(parent_tree){
7108                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7109                         "Security Information: 0x%08x", mask);
7110                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
7111         }
7112
7113         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
7114                 tvb, offset, 4, mask);
7115         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
7116                 tvb, offset, 4, mask);
7117         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
7118                 tvb, offset, 4, mask);
7119         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
7120                 tvb, offset, 4, mask);
7121
7122         offset += 4;
7123
7124         return offset;
7125 }
7126
7127 static void
7128 free_g_string(void *arg)
7129 {
7130         g_string_free(arg, TRUE);
7131 }
7132
7133 /* Dissect a NT SID.  Label it with 'name' and return a string version of
7134    the SID in the 'sid_str' parameter which must be freed by the caller.
7135    hf_sid can be -1 if the caller doesnt care what name is used and then 
7136    "smb.sid" will be the default instead. If the caller wants a more
7137    appropriate hf field, it will just pass a FT_STRING hf field here
7138 */
7139
7140 int
7141 dissect_nt_sid(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name,
7142                char **sid_str, int hf_sid)
7143 {
7144         proto_item *item = NULL;
7145         proto_tree *tree = NULL;
7146         int old_offset = offset, sa_offset = offset;
7147         gboolean rid_present;
7148         guint rid=0;
7149         int rid_offset=0;
7150         guint8 revision;
7151         int rev_offset;
7152         guint8 num_auth;
7153         int na_offset;
7154         guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
7155         int i;
7156         GString *gstr;
7157         char sid_string[245];
7158         char *sid_name;
7159
7160         if(hf_sid==-1){
7161                 hf_sid=hf_smb_sid;
7162         }
7163
7164         /* revision of sid */
7165         revision = tvb_get_guint8(tvb, offset);
7166         rev_offset = offset;
7167         offset += 1;
7168
7169         switch(revision){
7170         case 1:
7171         case 2:  /* Not sure what the different revision numbers mean */
7172           /* number of authorities*/
7173           num_auth = tvb_get_guint8(tvb, offset);
7174           na_offset = offset;
7175           offset += 1;
7176
7177           /* XXX perhaps we should have these thing searchable?
7178              a new FT_xxx thingie? SMB is quite common!*/
7179           /* identifier authorities */
7180
7181           for(i=0;i<6;i++){
7182             auth = (auth << 8) + tvb_get_guint8(tvb, offset);
7183
7184             offset++;
7185           }
7186
7187           sa_offset = offset;
7188
7189           gstr = g_string_new("");
7190
7191           CLEANUP_PUSH(free_g_string, gstr);
7192
7193           /* sub authorities, leave RID to last */
7194           for(i=0; i < (num_auth > 4?(num_auth - 1):num_auth); i++){
7195             /*
7196              * XXX should not be letohl but native byteorder according to
7197              * Samba header files.
7198              *
7199              * However, considering that there were never any NT ports
7200              * to big-endian platforms (PowerPC and MIPS ran little-endian,
7201              * and IA-64 runs little-endian, as does x86-64), we can (?)
7202              * assume that non le byte encodings will be "uncommon"?
7203              */
7204              g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"),
7205                   tvb_get_letohl(tvb, offset));
7206              offset+=4;
7207           }
7208
7209
7210           if (num_auth > 4) {
7211             rid = tvb_get_letohl(tvb, offset);
7212             rid_present=TRUE;
7213             rid_offset=offset;
7214             offset+=4;
7215             sprintf(sid_string, "S-1-%u-%s-%u", auth, gstr->str, rid);
7216           } else {
7217             rid_present=FALSE;
7218             sprintf(sid_string, "S-1-%u-%s", auth, gstr->str);
7219           }
7220
7221           sid_name=NULL;
7222           if(sid_name_snooping){
7223             sid_name=find_sid_name(sid_string);
7224           }
7225
7226           if(parent_tree){
7227             if(sid_name){
7228               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);
7229             } else {
7230               item = proto_tree_add_string_format(parent_tree, hf_sid, tvb, old_offset, offset-old_offset, sid_string, "%s: %s", name, sid_string);
7231             }
7232             tree = proto_item_add_subtree(item, ett_smb_sid);
7233           }
7234
7235           proto_tree_add_item(tree, hf_smb_sid_revision, tvb, rev_offset, 1, TRUE);
7236           proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, na_offset, 1, TRUE);
7237           proto_tree_add_text(tree, tvb, na_offset+1, 6, "Authority: %u", auth);
7238           proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
7239
7240           if(rid_present){
7241             proto_tree_add_text(tree, tvb, rid_offset, 4, "RID: %u", rid);
7242           }
7243
7244           if(sid_str){
7245             if(sid_name){
7246               *sid_str = g_strdup_printf("%s (%s)", sid_string, sid_name);
7247             } else {
7248               *sid_str = g_strdup(sid_string);
7249             }
7250           }
7251
7252           CLEANUP_CALL_AND_POP;
7253         }
7254
7255
7256         return offset;
7257 }
7258
7259
7260 static const value_string ace_type_vals[] = {
7261   { 0, "Access Allowed"},
7262   { 1, "Access Denied"},
7263   { 2, "System Audit"},
7264   { 3, "System Alarm"},
7265   { 0, NULL}
7266 };
7267 static const true_false_string tfs_ace_flags_object_inherit = {
7268   "Subordinate files will inherit this ACE",
7269   "Subordinate files will not inherit this ACE"
7270 };
7271 static const true_false_string tfs_ace_flags_container_inherit = {
7272   "Subordinate containers will inherit this ACE",
7273   "Subordinate containers will not inherit this ACE"
7274 };
7275 static const true_false_string tfs_ace_flags_non_propagate_inherit = {
7276   "Subordinate object will not propagate the inherited ACE further",
7277   "Subordinate object will propagate the inherited ACE further"
7278 };
7279 static const true_false_string tfs_ace_flags_inherit_only = {
7280   "This ACE does not apply to the current object",
7281   "This ACE applies to the current object"
7282 };
7283 static const true_false_string tfs_ace_flags_inherited_ace = {
7284   "This ACE was inherited from its parent object",
7285   "This ACE was not inherited from its parent object"
7286 };
7287 static const true_false_string tfs_ace_flags_successful_access = {
7288   "Successful accesses will be audited",
7289   "Successful accesses will not be audited"
7290 };
7291 static const true_false_string tfs_ace_flags_failed_access = {
7292   "Failed accesses will be audited",
7293   "Failed accesses will not be audited"
7294 };
7295
7296 #define APPEND_ACE_TEXT(flag, item, string) \
7297         if(flag){                                                       \
7298                 if(item)                                                \
7299                         proto_item_append_text(item, string, sep);      \
7300                 sep = ", ";                                             \
7301         }
7302
7303 static int
7304 dissect_nt_v2_ace_flags(tvbuff_t *tvb, int offset, proto_tree *parent_tree,
7305                         guint8 *data)
7306 {
7307         proto_item *item = NULL;
7308         proto_tree *tree = NULL;
7309         guint8 mask;
7310         char *sep = " ";
7311
7312         mask = tvb_get_guint8(tvb, offset);
7313
7314         if (data)
7315                 *data = mask;
7316
7317
7318         if(parent_tree){
7319                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7320                                            "NT ACE Flags: 0x%02x", mask);
7321                 tree = proto_item_add_subtree(item, ett_smb_ace_flags);
7322         }
7323
7324         proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
7325                        tvb, offset, 1, mask);
7326         APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
7327
7328         proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
7329                        tvb, offset, 1, mask);
7330         APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
7331
7332         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
7333                        tvb, offset, 1, mask);
7334         APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
7335
7336         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
7337                        tvb, offset, 1, mask);
7338         APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
7339
7340         proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
7341                        tvb, offset, 1, mask);
7342         APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
7343
7344         proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
7345                        tvb, offset, 1, mask);
7346         APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
7347
7348         proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
7349                        tvb, offset, 1, mask);
7350         APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
7351
7352
7353         offset += 1;
7354         return offset;
7355 }
7356
7357 /* Dissect an access mask.  All this stuff is kind of explained at MSDN:
7358
7359 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/windows_2000_windows_nt_access_mask_format.asp
7360
7361 */
7362
7363 static gint ett_nt_access_mask = -1;
7364 static gint ett_nt_access_mask_generic = -1;
7365 static gint ett_nt_access_mask_standard = -1;
7366 static gint ett_nt_access_mask_specific = -1;
7367
7368 static int hf_access_sacl = -1;
7369 static int hf_access_maximum_allowed = -1;
7370 static int hf_access_generic_read = -1;
7371 static int hf_access_generic_write = -1;
7372 static int hf_access_generic_execute = -1;
7373 static int hf_access_generic_all = -1;
7374 static int hf_access_standard_delete = -1;
7375 static int hf_access_standard_read_control = -1;
7376 static int hf_access_standard_synchronise = -1;
7377 static int hf_access_standard_write_dac = -1;
7378 static int hf_access_standard_write_owner = -1;
7379 static int hf_access_specific_15 = -1;
7380 static int hf_access_specific_14 = -1;
7381 static int hf_access_specific_13 = -1;
7382 static int hf_access_specific_12 = -1;
7383 static int hf_access_specific_11 = -1;
7384 static int hf_access_specific_10 = -1;
7385 static int hf_access_specific_9 = -1;
7386 static int hf_access_specific_8 = -1;
7387 static int hf_access_specific_7 = -1;
7388 static int hf_access_specific_6 = -1;
7389 static int hf_access_specific_5 = -1;
7390 static int hf_access_specific_4 = -1;
7391 static int hf_access_specific_3 = -1;
7392 static int hf_access_specific_2 = -1;
7393 static int hf_access_specific_1 = -1;
7394 static int hf_access_specific_0 = -1;
7395
7396 /* Map generic permissions to specific permissions */
7397
7398 static void map_generic_access(guint32 *access_mask, 
7399                                struct generic_mapping *mapping)
7400 {
7401         if (*access_mask & GENERIC_READ_ACCESS) {
7402                 *access_mask &= ~GENERIC_READ_ACCESS;
7403                 *access_mask |= mapping->generic_read;
7404         }
7405
7406         if (*access_mask & GENERIC_WRITE_ACCESS) {
7407                 *access_mask &= ~GENERIC_WRITE_ACCESS;
7408                 *access_mask |= mapping->generic_write;
7409         }
7410
7411         if (*access_mask & GENERIC_EXECUTE_ACCESS) {
7412                 *access_mask &= ~GENERIC_EXECUTE_ACCESS;
7413                 *access_mask |= mapping->generic_execute;
7414         }
7415
7416         if (*access_mask & GENERIC_ALL_ACCESS) {
7417                 *access_mask &= ~GENERIC_ALL_ACCESS;
7418                 *access_mask |= mapping->generic_all;
7419         }
7420 }
7421
7422 /* Map standard permissions to specific permissions */
7423
7424 static void map_standard_access(guint32 *access_mask,
7425                                 struct standard_mapping *mapping)
7426 {
7427         if (*access_mask & READ_CONTROL_ACCESS) {
7428                 *access_mask &= ~READ_CONTROL_ACCESS;
7429                 *access_mask |= mapping->std_read;
7430         }
7431
7432         if (*access_mask & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|
7433                             SYNCHRONIZE_ACCESS)) {
7434                 *access_mask &= ~(DELETE_ACCESS|WRITE_DAC_ACCESS|
7435                                   WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS);
7436                 *access_mask |= mapping->std_all;
7437         }
7438
7439 }
7440
7441 int
7442 dissect_nt_access_mask(tvbuff_t *tvb, gint offset, packet_info *pinfo,
7443                        proto_tree *tree, char *drep, int hfindex,
7444                        struct access_mask_info *ami)
7445 {
7446         proto_item *item;
7447         proto_tree *subtree, *generic_tree, *standard_tree, *specific_tree;
7448         guint32 access;
7449
7450         if (drep != NULL) {
7451                 /*
7452                  * Called from a DCE RPC protocol dissector, for a
7453                  * protocol where a 32-bit NDR integer contains
7454                  * an NT access mask; extract the access mask
7455                  * with an NDR call.
7456                  */
7457                 offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
7458                                             hfindex, &access);
7459         } else {
7460                 /*
7461                  * Called from SMB, where the access mask is just a
7462                  * 4-byte little-endian quantity with no special
7463                  * NDR alignment requirement; extract it with
7464                  * "tvb_get_letohl()".
7465                  */
7466                 access = tvb_get_letohl(tvb, offset);
7467                 offset += 4;
7468         }
7469
7470         item = proto_tree_add_uint(tree, hfindex, tvb, offset - 4, 4, access);
7471
7472         subtree = proto_item_add_subtree(item, ett_nt_access_mask);
7473
7474         /* Generic access rights */
7475
7476         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7477                                    "Generic rights: 0x%08x",
7478                                    access & GENERIC_RIGHTS_MASK);
7479
7480         generic_tree = proto_item_add_subtree(
7481                 item, ett_nt_access_mask_generic);
7482
7483         proto_tree_add_boolean(
7484                 generic_tree, hf_access_generic_read, tvb, offset - 4, 4,
7485                 access);
7486
7487         proto_tree_add_boolean(
7488                 generic_tree, hf_access_generic_write, tvb, offset - 4, 4,
7489                 access);
7490
7491         proto_tree_add_boolean(
7492                 generic_tree, hf_access_generic_execute, tvb, offset - 4, 4,
7493                 access);
7494
7495         proto_tree_add_boolean(
7496                 generic_tree, hf_access_generic_all, tvb, offset - 4, 4,
7497                 access);
7498
7499         /* Reserved (??) */
7500
7501         proto_tree_add_boolean(
7502                 subtree, hf_access_maximum_allowed, tvb, offset - 4, 4,
7503                 access);
7504
7505         /* Access system security */
7506
7507         proto_tree_add_boolean(
7508                 subtree, hf_access_sacl, tvb, offset - 4, 4,
7509                 access);
7510
7511         /* Standard access rights */
7512
7513         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7514                                    "Standard rights: 0x%08x",
7515                                    access & STANDARD_RIGHTS_MASK);
7516
7517         standard_tree = proto_item_add_subtree(
7518                 item, ett_nt_access_mask_standard);
7519
7520         proto_tree_add_boolean(
7521                 standard_tree, hf_access_standard_synchronise, tvb, 
7522                 offset - 4, 4, access);
7523
7524         proto_tree_add_boolean(
7525                 standard_tree, hf_access_standard_write_owner, tvb, 
7526                 offset - 4, 4, access);
7527
7528         proto_tree_add_boolean(
7529                 standard_tree, hf_access_standard_write_dac, tvb, 
7530                 offset - 4, 4, access);
7531
7532         proto_tree_add_boolean(
7533                 standard_tree, hf_access_standard_read_control, tvb, 
7534                 offset - 4, 4, access);
7535
7536         proto_tree_add_boolean(
7537                 standard_tree, hf_access_standard_delete, tvb, offset - 4, 4,
7538                 access);
7539
7540         /* Specific access rights.  Call the specific_rights_fn
7541            pointer if we have one, otherwise just display bits 0-15 in
7542            boring fashion. */
7543
7544         if (ami && ami->specific_rights_name)
7545                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7546                                            "%s specific rights: 0x%08x",
7547                                            ami->specific_rights_name,
7548                                            access & SPECIFIC_RIGHTS_MASK);
7549         else
7550                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7551                                            "Specific rights: 0x%08x",
7552                                            access & SPECIFIC_RIGHTS_MASK);
7553
7554         specific_tree = proto_item_add_subtree(
7555                 item, ett_nt_access_mask_specific);
7556
7557         if (ami && ami->specific_rights_fn) {
7558                 guint32 mapped_access = access;
7559                 proto_tree *specific_mapped;
7560
7561                 specific_mapped = proto_item_add_subtree(
7562                         item, ett_nt_access_mask_specific);
7563
7564                 ami->specific_rights_fn(
7565                         tvb, offset - 4, specific_tree, access);
7566
7567                 if (ami->generic_mapping)
7568                         map_generic_access(&access, ami->generic_mapping);
7569                 
7570                 if (ami->standard_mapping)
7571                         map_standard_access(&access, ami->standard_mapping);
7572
7573                 if (access != mapped_access) {
7574                         ami->specific_rights_fn(
7575                                 tvb, offset - 4, specific_mapped, 
7576                                 mapped_access);
7577                 }
7578                 
7579                 return offset;
7580         }
7581
7582         proto_tree_add_boolean(
7583                 specific_tree, hf_access_specific_15, tvb, offset - 4, 4,
7584                 access);
7585
7586         proto_tree_add_boolean(
7587                 specific_tree, hf_access_specific_14, tvb, offset - 4, 4,
7588                 access);
7589
7590         proto_tree_add_boolean(
7591                 specific_tree, hf_access_specific_13, tvb, offset - 4, 4,
7592                 access);
7593
7594         proto_tree_add_boolean(
7595                 specific_tree, hf_access_specific_12, tvb, offset - 4, 4,
7596                 access);
7597
7598         proto_tree_add_boolean(
7599                 specific_tree, hf_access_specific_11, tvb, offset - 4, 4,
7600                 access);
7601
7602         proto_tree_add_boolean(
7603                 specific_tree, hf_access_specific_10, tvb, offset - 4, 4,
7604                 access);
7605
7606         proto_tree_add_boolean(
7607                 specific_tree, hf_access_specific_9, tvb, offset - 4, 4,
7608                 access);
7609
7610         proto_tree_add_boolean(
7611                 specific_tree, hf_access_specific_8, tvb, offset - 4, 4,
7612                 access);
7613
7614         proto_tree_add_boolean(
7615                 specific_tree, hf_access_specific_7, tvb, offset - 4, 4,
7616                 access);
7617
7618         proto_tree_add_boolean(
7619                 specific_tree, hf_access_specific_6, tvb, offset - 4, 4,
7620                 access);
7621
7622         proto_tree_add_boolean(
7623                 specific_tree, hf_access_specific_5, tvb, offset - 4, 4,
7624                 access);
7625
7626         proto_tree_add_boolean(
7627                 specific_tree, hf_access_specific_4, tvb, offset - 4, 4,
7628                 access);
7629
7630         proto_tree_add_boolean(
7631                 specific_tree, hf_access_specific_3, tvb, offset - 4, 4,
7632                 access);
7633
7634         proto_tree_add_boolean(
7635                 specific_tree, hf_access_specific_2, tvb, offset - 4, 4,
7636                 access);
7637
7638         proto_tree_add_boolean(
7639                 specific_tree, hf_access_specific_1, tvb, offset - 4, 4,
7640                 access);
7641
7642         proto_tree_add_boolean(
7643                 specific_tree, hf_access_specific_0, tvb, offset - 4, 4,
7644                 access);
7645
7646         return offset;
7647 }
7648
7649 static int hf_smb_access_mask = -1;
7650
7651 static int
7652 dissect_nt_v2_ace(tvbuff_t *tvb, int offset, packet_info *pinfo,
7653                   proto_tree *parent_tree, char *drep,
7654                   struct access_mask_info *ami)
7655 {
7656         proto_item *item = NULL;
7657         proto_tree *tree = NULL;
7658         int old_offset = offset;
7659         guint16 size;
7660         char *sid_str = NULL;
7661         guint8 type;
7662         guint8 flags;
7663
7664         if(parent_tree){
7665                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7666                                            "NT ACE: ");
7667                 tree = proto_item_add_subtree(item, ett_smb_ace);
7668         }
7669
7670         /* type */
7671         type = tvb_get_guint8(tvb, offset);
7672         proto_tree_add_uint(tree, hf_smb_ace_type, tvb, offset, 1, type);
7673         offset += 1;
7674
7675         /* flags */
7676         offset = dissect_nt_v2_ace_flags(tvb, offset, tree, &flags);
7677
7678         /* size */
7679         size = tvb_get_letohs(tvb, offset);
7680         proto_tree_add_uint(tree, hf_smb_ace_size, tvb, offset, 2, size);
7681         offset += 2;
7682
7683         /* access mask */
7684         offset = dissect_nt_access_mask(
7685                 tvb, offset, pinfo, tree, drep, hf_smb_access_mask, ami);
7686
7687         /* SID */
7688         offset = dissect_nt_sid(tvb, offset, tree, "ACE", &sid_str, -1);
7689
7690         if (item)
7691                 proto_item_append_text(
7692                         item, "%s, flags 0x%02x, %s", sid_str, flags,
7693                         val_to_str(type, ace_type_vals, "Unknown ACE type (0x%02x)"));
7694
7695         g_free(sid_str);
7696
7697         proto_item_set_len(item, offset-old_offset);
7698
7699         /* Sometimes there is some spare space at the end of the ACE so use
7700            the size field to work out where the end is. */
7701
7702         return old_offset + size;
7703 }
7704
7705 static int
7706 dissect_nt_acl(tvbuff_t *tvb, int offset, packet_info *pinfo,
7707                proto_tree *parent_tree, char *drep, char *name,
7708                struct access_mask_info *ami)
7709 {
7710         proto_item *item = NULL;
7711         proto_tree *tree = NULL;
7712         int old_offset = offset;
7713         guint16 revision;
7714         guint32 num_aces;
7715
7716         if(parent_tree){
7717                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7718                                            "NT %s ACL", name);
7719                 tree = proto_item_add_subtree(item, ett_smb_acl);
7720         }
7721
7722         /* revision */
7723         revision = tvb_get_letohs(tvb, offset);
7724         proto_tree_add_uint(tree, hf_smb_acl_revision,
7725                 tvb, offset, 2, revision);
7726         offset += 2;
7727
7728         switch(revision){
7729         case 2:  /* only version we will ever see of this structure?*/
7730         case 3:
7731           /* size */
7732           proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
7733           offset += 2;
7734
7735           /* number of ace structures */
7736           num_aces = tvb_get_letohl(tvb, offset);
7737           proto_tree_add_uint(tree, hf_smb_acl_num_aces,
7738                               tvb, offset, 4, num_aces);
7739           offset += 4;
7740
7741           while(num_aces--){
7742             offset=dissect_nt_v2_ace(
7743                     tvb, offset, pinfo, tree, drep, ami);
7744           }
7745         }
7746
7747         proto_item_set_len(item, offset-old_offset);
7748         return offset;
7749 }
7750
7751 static const true_false_string tfs_sec_desc_type_owner_defaulted = {
7752   "OWNER is DEFAULTED",
7753   "Owner is NOT defaulted"
7754 };
7755 static const true_false_string tfs_sec_desc_type_group_defaulted = {
7756   "GROUP is DEFAULTED",
7757   "Group is NOT defaulted"
7758 };
7759 static const true_false_string tfs_sec_desc_type_dacl_present = {
7760   "DACL is PRESENT",
7761   "DACL is NOT present"
7762 };
7763 static const true_false_string tfs_sec_desc_type_dacl_defaulted = {
7764   "DACL is DEFAULTED",
7765   "DACL is NOT defaulted"
7766 };
7767 static const true_false_string tfs_sec_desc_type_sacl_present = {
7768   "SACL is PRESENT",
7769   "SACL is NOT present"
7770 };
7771 static const true_false_string tfs_sec_desc_type_sacl_defaulted = {
7772   "SACL is DEFAULTED",
7773   "SACL is NOT defaulted"
7774 };
7775 static const true_false_string tfs_sec_desc_type_dacl_auto_inherit_req = {
7776   "DACL has AUTO INHERIT REQUIRED",
7777   "DACL does NOT require auto inherit"
7778 };
7779 static const true_false_string tfs_sec_desc_type_sacl_auto_inherit_req = {
7780   "SACL has AUTO INHERIT REQUIRED",
7781   "SACL does NOT require auto inherit"
7782 };
7783 static const true_false_string tfs_sec_desc_type_dacl_auto_inherited = {
7784   "DACL is AUTO INHERITED",
7785   "DACL is NOT auto inherited"
7786 };
7787 static const true_false_string tfs_sec_desc_type_sacl_auto_inherited = {
7788   "SACL is AUTO INHERITED",
7789   "SACL is NOT auto inherited"
7790 };
7791 static const true_false_string tfs_sec_desc_type_dacl_protected = {
7792   "The DACL is PROTECTED",
7793   "The DACL is NOT protected"
7794 };
7795 static const true_false_string tfs_sec_desc_type_sacl_protected = {
7796   "The SACL is PROTECTED",
7797   "The SACL is NOT protected"
7798 };
7799 static const true_false_string tfs_sec_desc_type_self_relative = {
7800   "This SecDesc is SELF RELATIVE",
7801   "This SecDesc is NOT self relative"
7802 };
7803
7804
7805 static int
7806 dissect_nt_sec_desc_type(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7807 {
7808         proto_item *item = NULL;
7809         proto_tree *tree = NULL;
7810         guint16 mask;
7811
7812         mask = tvb_get_letohs(tvb, offset);
7813         if(parent_tree){
7814                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7815                                            "Type: 0x%04x", mask);
7816                 tree = proto_item_add_subtree(item, ett_smb_sec_desc_type);
7817         }
7818
7819         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_self_relative,
7820                                tvb, offset, 2, mask);
7821         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_protected,
7822                                tvb, offset, 2, mask);
7823         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_protected,
7824                                tvb, offset, 2, mask);
7825         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherited,
7826                                tvb, offset, 2, mask);
7827         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherited,
7828                                tvb, offset, 2, mask);
7829         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherit_req,
7830                                tvb, offset, 2, mask);
7831         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherit_req,
7832                                tvb, offset, 2, mask);
7833         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_defaulted,
7834                                tvb, offset, 2, mask);
7835         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_present,
7836                                tvb, offset, 2, mask);
7837         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_defaulted,
7838                                tvb, offset, 2, mask);
7839         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_present,
7840                                tvb, offset, 2, mask);
7841         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_group_defaulted,
7842                                tvb, offset, 2, mask);
7843         proto_tree_add_boolean(tree, hf_smb_sec_desc_type_owner_defaulted,
7844                                tvb, offset, 2, mask);
7845
7846
7847         offset += 2;
7848         return offset;
7849 }
7850
7851 int
7852 dissect_nt_sec_desc(tvbuff_t *tvb, int offset, packet_info *pinfo,
7853                     proto_tree *parent_tree, char *drep, int len, 
7854                     struct access_mask_info *ami)
7855 {
7856         proto_item *item = NULL;
7857         proto_tree *tree = NULL;
7858         guint8 revision;
7859         int old_offset = offset;
7860         guint32 owner_sid_offset;
7861         guint32 group_sid_offset;
7862         guint32 sacl_offset;
7863         guint32 dacl_offset;
7864
7865         if(parent_tree){
7866                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7867                                            "NT Security Descriptor");
7868                 tree = proto_item_add_subtree(item, ett_smb_sec_desc);
7869         }
7870
7871         /* revision */
7872         revision = tvb_get_guint8(tvb, offset);
7873         proto_tree_add_uint(tree, hf_smb_sec_desc_revision,
7874                 tvb, offset, 1, revision);
7875         offset += 1;
7876
7877         /* next byte should be zero, for now just ignore it */
7878         offset += 1;
7879
7880
7881         switch(revision){
7882         case 1:  /* only version we will ever see of this structure?*/
7883           /* type */
7884           offset = dissect_nt_sec_desc_type(tvb, offset, tree);
7885
7886           /* offset to owner sid */
7887           owner_sid_offset = tvb_get_letohl(tvb, offset);
7888           proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %u", owner_sid_offset);
7889           offset += 4;
7890
7891           /* offset to group sid */
7892           group_sid_offset = tvb_get_letohl(tvb, offset);
7893           proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %u", group_sid_offset);
7894           offset += 4;
7895
7896           /* offset to sacl */
7897           sacl_offset = tvb_get_letohl(tvb, offset);
7898           proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %u", sacl_offset);
7899           offset += 4;
7900
7901           /* offset to dacl */
7902           dacl_offset = tvb_get_letohl(tvb, offset);
7903           proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %u", dacl_offset);
7904           offset += 4;
7905
7906           /*owner SID*/
7907           if(owner_sid_offset){
7908             if (len == -1)
7909               offset = dissect_nt_sid(tvb, offset, tree, "Owner", NULL, -1);
7910             else
7911               dissect_nt_sid(
7912                       tvb, old_offset+owner_sid_offset, tree, "Owner", NULL, -1);
7913           }
7914
7915           /*group SID*/
7916           if(group_sid_offset){
7917             dissect_nt_sid(
7918                     tvb, old_offset+group_sid_offset, tree, "Group", NULL, -1);
7919           }
7920
7921           /* sacl */
7922           if(sacl_offset){
7923             dissect_nt_acl(tvb, old_offset+sacl_offset, pinfo, tree, 
7924                            drep, "System (SACL)", ami);
7925           }
7926
7927           /* dacl */
7928           if(dacl_offset){
7929             dissect_nt_acl(tvb, old_offset+dacl_offset, pinfo, tree, 
7930                            drep, "User (DACL)", ami);
7931           }
7932
7933         }
7934
7935         return offset+len;
7936 }
7937
7938 static int
7939 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
7940 {
7941         int old_offset, old_sid_offset;
7942         guint32 qsize;
7943
7944         do {
7945                 old_offset=offset;
7946
7947                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7948                 qsize=tvb_get_letohl(tvb, offset);
7949                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
7950                 COUNT_BYTES_TRANS_SUBR(4);
7951
7952                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7953                 /* length of SID */
7954                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7955                 COUNT_BYTES_TRANS_SUBR(4);
7956
7957                 /* 16 unknown bytes */
7958                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7959                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7960                             offset, 8, TRUE);
7961                 COUNT_BYTES_TRANS_SUBR(8);
7962
7963                 /* number of bytes for used quota */
7964                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7965                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
7966                 COUNT_BYTES_TRANS_SUBR(8);
7967
7968                 /* number of bytes for quota warning */
7969                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7970                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
7971                 COUNT_BYTES_TRANS_SUBR(8);
7972
7973                 /* number of bytes for quota limit */
7974                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7975                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
7976                 COUNT_BYTES_TRANS_SUBR(8);
7977
7978                 /* SID of the user */
7979                 old_sid_offset=offset;
7980                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
7981                 *bcp -= (offset-old_sid_offset);
7982
7983                 if(qsize){
7984                         offset = old_offset+qsize;
7985                 }
7986         }while(qsize);
7987
7988
7989         return offset;
7990 }
7991
7992
7993 static int
7994 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
7995 {
7996         proto_item *item = NULL;
7997         proto_tree *tree = NULL;
7998         smb_info_t *si;
7999         int old_offset = offset;
8000         guint16 bcp=bc; /* XXX fixme */
8001
8002         si = (smb_info_t *)pinfo->private_data;
8003
8004         if(parent_tree){
8005                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
8006                                 "%s Data",
8007                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8008                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8009         }
8010
8011         switch(ntd->subcmd){
8012         case NT_TRANS_CREATE:
8013                 /* security descriptor */
8014                 if(ntd->sd_len){
8015                         offset = dissect_nt_sec_desc(
8016                                 tvb, offset, pinfo, tree, NULL, ntd->sd_len, 
8017                                 NULL);
8018                 }
8019
8020                 /* extended attributes */
8021                 if(ntd->ea_len){
8022                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
8023                         offset += ntd->ea_len;
8024                 }
8025
8026                 break;
8027         case NT_TRANS_IOCTL:
8028                 /* ioctl data */
8029                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
8030                 offset += bc;
8031
8032                 break;
8033         case NT_TRANS_SSD:
8034                 offset = dissect_nt_sec_desc(
8035                         tvb, offset, pinfo, tree, NULL, bc, NULL);
8036                 break;
8037         case NT_TRANS_NOTIFY:
8038                 break;
8039         case NT_TRANS_RENAME:
8040                 /* XXX not documented */
8041                 break;
8042         case NT_TRANS_QSD:
8043                 break;
8044         case NT_TRANS_GET_USER_QUOTA:
8045                 /* unknown 4 bytes */
8046                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8047                             offset, 4, TRUE);
8048                 offset += 4;
8049
8050                 /* length of SID */
8051                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
8052                 offset +=4;
8053
8054                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8055                 break;
8056         case NT_TRANS_SET_USER_QUOTA:
8057                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8058                 break;
8059         }
8060
8061         /* ooops there were data we didnt know how to process */
8062         if((offset-old_offset) < bc){
8063                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
8064                     bc - (offset-old_offset), TRUE);
8065                 offset += bc - (offset-old_offset);
8066         }
8067
8068         return offset;
8069 }
8070
8071 static int
8072 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)
8073 {
8074         proto_item *item = NULL;
8075         proto_tree *tree = NULL;
8076         smb_info_t *si;
8077         guint32 fn_len;
8078         const char *fn;
8079
8080         si = (smb_info_t *)pinfo->private_data;
8081
8082         if(parent_tree){
8083                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8084                                 "%s Parameters",
8085                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8086                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8087         }
8088
8089         switch(ntd->subcmd){
8090         case NT_TRANS_CREATE:
8091                 /* Create flags */
8092                 offset = dissect_nt_create_bits(tvb, tree, offset);
8093                 bc -= 4;
8094
8095                 /* root directory fid */
8096                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
8097                 COUNT_BYTES(4);
8098
8099                 /* nt access mask */
8100                 offset = dissect_smb_access_mask(tvb, tree, offset);
8101                 bc -= 4;
8102
8103                 /* allocation size */
8104                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8105                 COUNT_BYTES(8);
8106
8107                 /* Extended File Attributes */
8108                 offset = dissect_file_ext_attr(tvb, tree, offset);
8109                 bc -= 4;
8110
8111                 /* share access */
8112                 offset = dissect_nt_share_access(tvb, tree, offset);
8113                 bc -= 4;
8114
8115                 /* create disposition */
8116                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8117                 COUNT_BYTES(4);
8118
8119                 /* create options */
8120                 offset = dissect_nt_create_options(tvb, tree, offset);
8121                 bc -= 4;
8122
8123                 /* sd length */
8124                 ntd->sd_len = tvb_get_letohl(tvb, offset);
8125                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
8126                 COUNT_BYTES(4);
8127
8128                 /* ea length */
8129                 ntd->ea_len = tvb_get_letohl(tvb, offset);
8130                 proto_tree_add_uint(tree, hf_smb_ea_list_length, tvb, offset, 4, ntd->ea_len);
8131                 COUNT_BYTES(4);
8132
8133                 /* file name len */
8134                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
8135                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8136                 COUNT_BYTES(4);
8137
8138                 /* impersonation level */
8139                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8140                 COUNT_BYTES(4);
8141
8142                 /* security flags */
8143                 offset = dissect_nt_security_flags(tvb, tree, offset);
8144                 bc -= 1;
8145
8146                 /* file name */
8147                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8148                 if (fn != NULL) {
8149                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8150                                 fn);
8151                         COUNT_BYTES(fn_len);
8152                 }
8153
8154                 break;
8155         case NT_TRANS_IOCTL:
8156                 break;
8157         case NT_TRANS_SSD: {
8158                 guint16 fid;
8159
8160                 /* fid */
8161                 fid = tvb_get_letohs(tvb, offset);
8162                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8163                 offset += 2;
8164
8165                 /* 2 reserved bytes */
8166                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8167                 offset += 2;
8168
8169                 /* security information */
8170                 offset = dissect_security_information_mask(tvb, tree, offset);
8171                 break;
8172         }
8173         case NT_TRANS_NOTIFY:
8174                 break;
8175         case NT_TRANS_RENAME:
8176                 /* XXX not documented */
8177                 break;
8178         case NT_TRANS_QSD: {
8179                 guint16 fid;
8180
8181                 /* fid */
8182                 fid = tvb_get_letohs(tvb, offset);
8183                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8184                 offset += 2;
8185
8186                 /* 2 reserved bytes */
8187                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8188                 offset += 2;
8189
8190                 /* security information */
8191                 offset = dissect_security_information_mask(tvb, tree, offset);
8192                 break;
8193         }
8194         case NT_TRANS_GET_USER_QUOTA:
8195                 /* not decoded yet */
8196                 break;
8197         case NT_TRANS_SET_USER_QUOTA:
8198                 /* not decoded yet */
8199                 break;
8200         }
8201
8202         return offset;
8203 }
8204
8205 static int
8206 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
8207 {
8208         proto_item *item = NULL;
8209         proto_tree *tree = NULL;
8210         smb_info_t *si;
8211         int old_offset = offset;
8212
8213         si = (smb_info_t *)pinfo->private_data;
8214
8215         if(parent_tree){
8216                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8217                                 "%s Setup",
8218                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8219                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8220         }
8221
8222         switch(ntd->subcmd){
8223         case NT_TRANS_CREATE:
8224                 break;
8225         case NT_TRANS_IOCTL: {
8226                 guint16 fid;
8227
8228                 /* function code */
8229                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
8230                 offset += 4;
8231
8232                 /* fid */
8233                 fid = tvb_get_letohs(tvb, offset);
8234                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8235                 offset += 2;
8236
8237                 /* isfsctl */
8238                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
8239                 offset += 1;
8240
8241                 /* isflags */
8242                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
8243
8244                 break;
8245         }
8246         case NT_TRANS_SSD:
8247                 break;
8248         case NT_TRANS_NOTIFY: {
8249                 guint16 fid;
8250
8251                 /* completion filter */
8252                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
8253
8254                 /* fid */
8255                 fid = tvb_get_letohs(tvb, offset);
8256                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8257                 offset += 2;
8258
8259                 /* watch tree */
8260                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
8261                 offset += 1;
8262
8263                 /* reserved byte */
8264                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8265                 offset += 1;
8266
8267                 break;
8268         }
8269         case NT_TRANS_RENAME:
8270                 /* XXX not documented */
8271                 break;
8272         case NT_TRANS_QSD:
8273                 break;
8274         case NT_TRANS_GET_USER_QUOTA:
8275                 /* not decoded yet */
8276                 break;
8277         case NT_TRANS_SET_USER_QUOTA:
8278                 /* not decoded yet */
8279                 break;
8280         }
8281
8282         return old_offset+len;
8283 }
8284
8285
8286 static int
8287 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8288 {
8289         guint8 wc, sc;
8290         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
8291         smb_info_t *si;
8292         smb_saved_info_t *sip;
8293         int subcmd;
8294         nt_trans_data ntd;
8295         guint16 bc;
8296         int padcnt;
8297         smb_nt_transact_info_t *nti;
8298
8299         si = (smb_info_t *)pinfo->private_data;
8300         sip = si->sip;
8301
8302         WORD_COUNT;
8303
8304         if(wc>=19){
8305                 /* primary request */
8306                 /* max setup count */
8307                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
8308                 offset += 1;
8309
8310                 /* 2 reserved bytes */
8311                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8312                 offset += 2;
8313         } else {
8314                 /* secondary request */
8315                 /* 3 reserved bytes */
8316                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8317                 offset += 3;
8318         }
8319
8320
8321         /* total param count */
8322         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
8323         offset += 4;
8324
8325         /* total data count */
8326         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
8327         offset += 4;
8328
8329         if(wc>=19){
8330                 /* primary request */
8331                 /* max param count */
8332                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
8333                 offset += 4;
8334
8335                 /* max data count */
8336                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
8337                 offset += 4;
8338         }
8339
8340         /* param count */
8341         pc = tvb_get_letohl(tvb, offset);
8342         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8343         offset += 4;
8344
8345         /* param offset */
8346         po = tvb_get_letohl(tvb, offset);
8347         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8348         offset += 4;
8349
8350         /* param displacement */
8351         if(wc>=19){
8352                 /* primary request*/
8353                 pd = 0;
8354         } else {
8355                 /* secondary request */
8356                 pd = tvb_get_letohl(tvb, offset);
8357                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8358                 offset += 4;
8359         }
8360
8361         /* data count */
8362         dc = tvb_get_letohl(tvb, offset);
8363         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8364         offset += 4;
8365
8366         /* data offset */
8367         od = tvb_get_letohl(tvb, offset);
8368         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8369         offset += 4;
8370
8371         /* data displacement */
8372         if(wc>=19){
8373                 /* primary request */
8374                 dd = 0;
8375         } else {
8376                 /* secondary request */
8377                 dd = tvb_get_letohl(tvb, offset);
8378                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8379                 offset += 4;
8380         }
8381
8382         /* setup count */
8383         if(wc>=19){
8384                 /* primary request */
8385                 sc = tvb_get_guint8(tvb, offset);
8386                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8387                 offset += 1;
8388         } else {
8389                 /* secondary request */
8390                 sc = 0;
8391         }
8392
8393         /* function */
8394         if(wc>=19){
8395                 /* primary request */
8396                 subcmd = tvb_get_letohs(tvb, offset);
8397                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
8398                 if(check_col(pinfo->cinfo, COL_INFO)){
8399                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8400                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
8401                 }
8402                 ntd.subcmd = subcmd;
8403                 if (!si->unidir) {
8404                         if(!pinfo->fd->flags.visited){
8405                                 /*
8406                                  * Allocate a new smb_nt_transact_info_t
8407                                  * structure.
8408                                  */
8409                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
8410                                 nti->subcmd = subcmd;
8411                                 sip->extra_info = nti;
8412                         }
8413                 }
8414         } else {
8415                 /* secondary request */
8416                 if(check_col(pinfo->cinfo, COL_INFO)){
8417                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
8418                 }
8419         }
8420         offset += 2;
8421
8422         /* this is a padding byte */
8423         if(offset%1){
8424                 /* pad byte */
8425                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
8426                 offset += 1;
8427         }
8428
8429         /* if there were any setup bytes, decode them */
8430         if(sc){
8431                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
8432                 offset += sc*2;
8433         }
8434
8435         BYTE_COUNT;
8436
8437         /* parameters */
8438         if(po>(guint32)offset){
8439                 /* We have some initial padding bytes.
8440                 */
8441                 padcnt = po-offset;
8442                 if (padcnt > bc)
8443                         padcnt = bc;
8444                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8445                 COUNT_BYTES(padcnt);
8446         }
8447         if(pc){
8448                 CHECK_BYTE_COUNT(pc);
8449                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
8450                 COUNT_BYTES(pc);
8451         }
8452
8453         /* data */
8454         if(od>(guint32)offset){
8455                 /* We have some initial padding bytes.
8456                 */
8457                 padcnt = od-offset;
8458                 if (padcnt > bc)
8459                         padcnt = bc;
8460                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8461                 COUNT_BYTES(padcnt);
8462         }
8463         if(dc){
8464                 CHECK_BYTE_COUNT(dc);
8465                 dissect_nt_trans_data_request(
8466                         tvb, pinfo, offset, tree, dc, &ntd);
8467                 COUNT_BYTES(dc);
8468         }
8469
8470         END_OF_SMB
8471
8472         return offset;
8473 }
8474
8475
8476
8477 static int
8478 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
8479                                int offset, proto_tree *parent_tree, int len,
8480                                nt_trans_data *ntd _U_)
8481 {
8482         proto_item *item = NULL;
8483         proto_tree *tree = NULL;
8484         smb_info_t *si;
8485         smb_nt_transact_info_t *nti;
8486         guint16 bcp;
8487
8488         si = (smb_info_t *)pinfo->private_data;
8489         if (si->sip != NULL)
8490                 nti = si->sip->extra_info;
8491         else
8492                 nti = NULL;
8493
8494         if(parent_tree){
8495                 if(nti != NULL){
8496                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8497                                 "%s Data",
8498                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8499                 } else {
8500                         /*
8501                          * We never saw the request to which this is a
8502                          * response.
8503                          */
8504                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8505                                 "Unknown NT Transaction Data (matching request not seen)");
8506                 }
8507                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8508         }
8509
8510         if (nti == NULL) {
8511                 offset += len;
8512                 return offset;
8513         }
8514         switch(nti->subcmd){
8515         case NT_TRANS_CREATE:
8516                 break;
8517         case NT_TRANS_IOCTL:
8518                 /* ioctl data */
8519                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
8520                 offset += len;
8521
8522                 break;
8523         case NT_TRANS_SSD:
8524                 break;
8525         case NT_TRANS_NOTIFY:
8526                 break;
8527         case NT_TRANS_RENAME:
8528                 /* XXX not documented */
8529                 break;
8530         case NT_TRANS_QSD: {
8531                 /*
8532                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
8533                  * which may be documented in the Win32 documentation
8534                  * somewhere.
8535                  */
8536                 offset = dissect_nt_sec_desc(
8537                         tvb, offset, pinfo, tree, NULL, len, NULL);
8538                 break;
8539         }
8540         case NT_TRANS_GET_USER_QUOTA:
8541                 bcp=len;
8542                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8543                 break;
8544         case NT_TRANS_SET_USER_QUOTA:
8545                 /* not decoded yet */
8546                 break;
8547         }
8548
8549         return offset;
8550 }
8551
8552 static int
8553 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
8554                                 int offset, proto_tree *parent_tree,
8555                                 int len, nt_trans_data *ntd _U_, guint16 bc)
8556 {
8557         proto_item *item = NULL;
8558         proto_tree *tree = NULL;
8559         guint32 fn_len;
8560         const char *fn;
8561         smb_info_t *si;
8562         smb_nt_transact_info_t *nti;
8563         guint16 fid;
8564         int old_offset;
8565         guint32 neo;
8566         int padcnt;
8567
8568         si = (smb_info_t *)pinfo->private_data;
8569         if (si->sip != NULL)
8570                 nti = si->sip->extra_info;
8571         else
8572                 nti = NULL;
8573
8574         if(parent_tree){
8575                 if(nti != NULL){
8576                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8577                                 "%s Parameters",
8578                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8579                 } else {
8580                         /*
8581                          * We never saw the request to which this is a
8582                          * response.
8583                          */
8584                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8585                                 "Unknown NT Transaction Parameters (matching request not seen)");
8586                 }
8587                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8588         }
8589
8590         if (nti == NULL) {
8591                 offset += len;
8592                 return offset;
8593         }
8594         switch(nti->subcmd){
8595         case NT_TRANS_CREATE:
8596                 /* oplock level */
8597                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8598                 offset += 1;
8599
8600                 /* reserved byte */
8601                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8602                 offset += 1;
8603
8604                 /* fid */
8605                 fid = tvb_get_letohs(tvb, offset);
8606                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8607                 offset += 2;
8608
8609                 /* create action */
8610                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8611                 offset += 4;
8612
8613                 /* ea error offset */
8614                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
8615                 offset += 4;
8616
8617                 /* create time */
8618                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8619                         hf_smb_create_time);
8620
8621                 /* access time */
8622                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8623                         hf_smb_access_time);
8624
8625                 /* last write time */
8626                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8627                         hf_smb_last_write_time);
8628
8629                 /* last change time */
8630                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8631                         hf_smb_change_time);
8632
8633                 /* Extended File Attributes */
8634                 offset = dissect_file_ext_attr(tvb, tree, offset);
8635
8636                 /* allocation size */
8637                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8638                 offset += 8;
8639
8640                 /* end of file */
8641                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8642                 offset += 8;
8643
8644                 /* File Type */
8645                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8646                 offset += 2;
8647
8648                 /* device state */
8649                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8650
8651                 /* is directory */
8652                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8653                 offset += 1;
8654                 break;
8655         case NT_TRANS_IOCTL:
8656                 break;
8657         case NT_TRANS_SSD:
8658                 break;
8659         case NT_TRANS_NOTIFY:
8660                 while(len){
8661                         old_offset = offset;
8662
8663                         /* next entry offset */
8664                         neo = tvb_get_letohl(tvb, offset);
8665                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8666                         COUNT_BYTES(4);
8667                         len -= 4;
8668                         /* broken implementations */
8669                         if(len<0)break;
8670
8671                         /* action */
8672                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
8673                         COUNT_BYTES(4);
8674                         len -= 4;
8675                         /* broken implementations */
8676                         if(len<0)break;
8677
8678                         /* file name len */
8679                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
8680                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8681                         COUNT_BYTES(4);
8682                         len -= 4;
8683                         /* broken implementations */
8684                         if(len<0)break;
8685
8686                         /* file name */
8687                         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8688                         if (fn == NULL)
8689                                 break;
8690                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8691                                 fn);
8692                         COUNT_BYTES(fn_len);
8693                         len -= fn_len;
8694                         /* broken implementations */
8695                         if(len<0)break;
8696
8697                         if (neo == 0)
8698                                 break;  /* no more structures */
8699
8700                         /* skip to next structure */
8701                         padcnt = (old_offset + neo) - offset;
8702                         if (padcnt < 0) {
8703                                 /*
8704                                  * XXX - this is bogus; flag it?
8705                                  */
8706                                 padcnt = 0;
8707                         }
8708                         if (padcnt != 0) {
8709                                 COUNT_BYTES(padcnt);
8710                                 len -= padcnt;
8711                                 /* broken implementations */
8712                                 if(len<0)break;
8713                         }
8714                 }
8715                 break;
8716         case NT_TRANS_RENAME:
8717                 /* XXX not documented */
8718                 break;
8719         case NT_TRANS_QSD:
8720                 /*
8721                  * This appears to be the size of the security
8722                  * descriptor; the calling sequence of
8723                  * "ZwQuerySecurityObject()" suggests that it would
8724                  * be.  The actual security descriptor wouldn't
8725                  * follow if the max data count in the request
8726                  * was smaller; this lets the client know how
8727                  * big a buffer it needs to provide.
8728                  */
8729                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
8730                 offset += 4;
8731                 break;
8732         case NT_TRANS_GET_USER_QUOTA:
8733                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
8734                         tvb_get_letohl(tvb, offset));
8735                 offset += 4;
8736                 break;
8737         case NT_TRANS_SET_USER_QUOTA:
8738                 /* not decoded yet */
8739                 break;
8740         }
8741
8742         return offset;
8743 }
8744
8745 static int
8746 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
8747                                 int offset, proto_tree *parent_tree,
8748                                 int len, nt_trans_data *ntd _U_)
8749 {
8750         proto_item *item = NULL;
8751         proto_tree *tree = NULL;
8752         smb_info_t *si;
8753         smb_nt_transact_info_t *nti;
8754
8755         si = (smb_info_t *)pinfo->private_data;
8756         if (si->sip != NULL)
8757                 nti = si->sip->extra_info;
8758         else
8759                 nti = NULL;
8760
8761         if(parent_tree){
8762                 if(nti != NULL){
8763                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8764                                 "%s Setup",
8765                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8766                 } else {
8767                         /*
8768                          * We never saw the request to which this is a
8769                          * response.
8770                          */
8771                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8772                                 "Unknown NT Transaction Setup (matching request not seen)");
8773                 }
8774                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8775         }
8776
8777         if (nti == NULL) {
8778                 offset += len;
8779                 return offset;
8780         }
8781         switch(nti->subcmd){
8782         case NT_TRANS_CREATE:
8783                 break;
8784         case NT_TRANS_IOCTL:
8785                 break;
8786         case NT_TRANS_SSD:
8787                 break;
8788         case NT_TRANS_NOTIFY:
8789                 break;
8790         case NT_TRANS_RENAME:
8791                 /* XXX not documented */
8792                 break;
8793         case NT_TRANS_QSD:
8794                 break;
8795         case NT_TRANS_GET_USER_QUOTA:
8796                 /* not decoded yet */
8797                 break;
8798         case NT_TRANS_SET_USER_QUOTA:
8799                 /* not decoded yet */
8800                 break;
8801         }
8802
8803         return offset;
8804 }
8805
8806 static int
8807 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8808 {
8809         guint8 wc, sc;
8810         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
8811         guint32 td=0, tp=0;
8812         smb_info_t *si;
8813         smb_nt_transact_info_t *nti;
8814         static nt_trans_data ntd;
8815         guint16 bc;
8816         int padcnt;
8817         fragment_data *r_fd = NULL;
8818         tvbuff_t *pd_tvb=NULL;
8819         gboolean save_fragmented;
8820
8821         si = (smb_info_t *)pinfo->private_data;
8822         if (si->sip != NULL)
8823                 nti = si->sip->extra_info;
8824         else
8825                 nti = NULL;
8826
8827         /* primary request */
8828         if(nti != NULL){
8829                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
8830                 if(check_col(pinfo->cinfo, COL_INFO)){
8831                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8832                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
8833                 }
8834         } else {
8835                 proto_tree_add_text(tree, tvb, offset, 0,
8836                         "Function: <unknown function - could not find matching request>");
8837                 if(check_col(pinfo->cinfo, COL_INFO)){
8838                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
8839                 }
8840         }
8841
8842         WORD_COUNT;
8843
8844         /* 3 reserved bytes */
8845         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8846         offset += 3;
8847
8848         /* total param count */
8849         tp = tvb_get_letohl(tvb, offset);
8850         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8851         offset += 4;
8852
8853         /* total data count */
8854         td = tvb_get_letohl(tvb, offset);
8855         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8856         offset += 4;
8857
8858         /* param count */
8859         pc = tvb_get_letohl(tvb, offset);
8860         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8861         offset += 4;
8862
8863         /* param offset */
8864         po = tvb_get_letohl(tvb, offset);
8865         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8866         offset += 4;
8867
8868         /* param displacement */
8869         pd = tvb_get_letohl(tvb, offset);
8870         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8871         offset += 4;
8872
8873         /* data count */
8874         dc = tvb_get_letohl(tvb, offset);
8875         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8876         offset += 4;
8877
8878         /* data offset */
8879         od = tvb_get_letohl(tvb, offset);
8880         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8881         offset += 4;
8882
8883         /* data displacement */
8884         dd = tvb_get_letohl(tvb, offset);
8885         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8886         offset += 4;
8887
8888         /* setup count */
8889         sc = tvb_get_guint8(tvb, offset);
8890         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8891         offset += 1;
8892
8893         /* setup data */
8894         if(sc){
8895                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
8896                 offset += sc*2;
8897         }
8898
8899         BYTE_COUNT;
8900
8901         /* reassembly of SMB NT Transaction data payload.
8902            In this section we do reassembly of both the data and parameters
8903            blocks of the SMB transaction command.
8904         */
8905         save_fragmented = pinfo->fragmented;
8906         /* do we need reassembly? */
8907         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
8908                 /* oh yeah, either data or parameter section needs
8909                    reassembly...
8910                 */
8911                 pinfo->fragmented = TRUE;
8912                 if(smb_trans_reassembly){
8913                         /* ...and we were told to do reassembly */
8914                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
8915                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8916                                                              po, pc, pd, td+tp);
8917
8918                         }
8919                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
8920                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8921                                                              od, dc, dd+tp, td+tp);
8922                         }
8923                 }
8924         }
8925
8926         /* if we got a reassembled fd structure from the reassembly routine we
8927            must create pd_tvb from it
8928         */
8929         if(r_fd){
8930                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
8931                                              r_fd->datalen);
8932                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
8933                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
8934
8935                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
8936         }
8937
8938
8939         if(pd_tvb){
8940           /* we have reassembled data, grab param and data from there */
8941           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
8942                                           &ntd, tvb_length(pd_tvb));
8943           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
8944         } else {
8945           /* we do not have reassembled data, just use what we have in the
8946              packet as well as we can */
8947           /* parameters */
8948           if(po>(guint32)offset){
8949             /* We have some initial padding bytes.
8950              */
8951             padcnt = po-offset;
8952             if (padcnt > bc)
8953               padcnt = bc;
8954             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8955             COUNT_BYTES(padcnt);
8956           }
8957           if(pc){
8958             CHECK_BYTE_COUNT(pc);
8959             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
8960             COUNT_BYTES(pc);
8961           }
8962
8963           /* data */
8964           if(od>(guint32)offset){
8965             /* We have some initial padding bytes.
8966              */
8967             padcnt = od-offset;
8968             if (padcnt > bc)
8969               padcnt = bc;
8970             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8971             COUNT_BYTES(padcnt);
8972           }
8973           if(dc){
8974             CHECK_BYTE_COUNT(dc);
8975             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
8976             COUNT_BYTES(dc);
8977           }
8978         }
8979         pinfo->fragmented = save_fragmented;
8980
8981         END_OF_SMB
8982
8983         return offset;
8984 }
8985
8986 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8987    NT Transaction command  ends here
8988    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8989
8990 static const value_string print_mode_vals[] = {
8991         {0,     "Text Mode"},
8992         {1,     "Graphics Mode"},
8993         {0, NULL}
8994 };
8995
8996 static int
8997 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8998 {
8999         smb_info_t *si = pinfo->private_data;
9000         int fn_len;
9001         const char *fn;
9002         guint8 wc;
9003         guint16 bc;
9004
9005         WORD_COUNT;
9006
9007         /* setup len */
9008         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
9009         offset += 2;
9010
9011         /* print mode */
9012         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
9013         offset += 2;
9014
9015         BYTE_COUNT;
9016
9017         /* buffer format */
9018         CHECK_BYTE_COUNT(1);
9019         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9020         COUNT_BYTES(1);
9021
9022         /* print identifier */
9023         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
9024         if (fn == NULL)
9025                 goto endofcommand;
9026         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
9027                 fn);
9028         COUNT_BYTES(fn_len);
9029
9030         END_OF_SMB
9031
9032         return offset;
9033 }
9034
9035
9036 static int
9037 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9038 {
9039         int cnt;
9040         guint8 wc;
9041         guint16 bc, fid;
9042
9043         WORD_COUNT;
9044
9045         /* fid */
9046         fid = tvb_get_letohs(tvb, offset);
9047         add_fid(tvb, pinfo, tree, offset, 2, fid);
9048         offset += 2;
9049
9050         BYTE_COUNT;
9051
9052         /* buffer format */
9053         CHECK_BYTE_COUNT(1);
9054         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9055         COUNT_BYTES(1);
9056
9057         /* data len */
9058         CHECK_BYTE_COUNT(2);
9059         cnt = tvb_get_letohs(tvb, offset);
9060         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
9061         COUNT_BYTES(2);
9062
9063         /* file data */
9064         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
9065
9066         END_OF_SMB
9067
9068         return offset;
9069 }
9070
9071
9072 static const value_string print_status_vals[] = {
9073         {1,     "Held or Stopped"},
9074         {2,     "Printing"},
9075         {3,     "Awaiting print"},
9076         {4,     "In intercept"},
9077         {5,     "File had error"},
9078         {6,     "Printer error"},
9079         {0, NULL}
9080 };
9081
9082 static int
9083 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9084 {
9085         guint8 wc;
9086         guint16 bc;
9087
9088         WORD_COUNT;
9089
9090         /* max count */
9091         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
9092         offset += 2;
9093
9094         /* start index */
9095         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
9096         offset += 2;
9097
9098         BYTE_COUNT;
9099
9100         END_OF_SMB
9101
9102         return offset;
9103 }
9104
9105 static int
9106 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
9107     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
9108 {
9109         proto_item *item = NULL;
9110         proto_tree *tree = NULL;
9111         smb_info_t *si = pinfo->private_data;
9112         int fn_len;
9113         const char *fn;
9114
9115         if(parent_tree){
9116                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
9117                         "Queue entry");
9118                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
9119         }
9120
9121         /* queued time */
9122         CHECK_BYTE_COUNT_SUBR(4);
9123         offset = dissect_smb_datetime(tvb, tree, offset,
9124                 hf_smb_print_queue_date,
9125                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
9126         *bcp -= 4;
9127
9128         /* status */
9129         CHECK_BYTE_COUNT_SUBR(1);
9130         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
9131         COUNT_BYTES_SUBR(1);
9132
9133         /* spool file number */
9134         CHECK_BYTE_COUNT_SUBR(2);
9135         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
9136         COUNT_BYTES_SUBR(2);
9137
9138         /* spool file size */
9139         CHECK_BYTE_COUNT_SUBR(4);
9140         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
9141         COUNT_BYTES_SUBR(4);
9142
9143         /* reserved byte */
9144         CHECK_BYTE_COUNT_SUBR(1);
9145         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9146         COUNT_BYTES_SUBR(1);
9147
9148         /* file name */
9149         fn_len = 16;
9150         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
9151         CHECK_STRING_SUBR(fn);
9152         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
9153                 fn);
9154         COUNT_BYTES_SUBR(fn_len);
9155
9156         *trunc = FALSE;
9157         return offset;
9158 }
9159
9160 static int
9161 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9162 {
9163         guint16 cnt=0, len;
9164         guint8 wc;
9165         guint16 bc;
9166         gboolean trunc;
9167
9168         WORD_COUNT;
9169
9170         /* count */
9171         cnt = tvb_get_letohs(tvb, offset);
9172         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
9173         offset += 2;
9174
9175         /* restart index */
9176         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
9177         offset += 2;
9178
9179         BYTE_COUNT;
9180
9181         /* buffer format */
9182         CHECK_BYTE_COUNT(1);
9183         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9184         COUNT_BYTES(1);
9185
9186         /* data len */
9187         CHECK_BYTE_COUNT(2);
9188         len = tvb_get_letohs(tvb, offset);
9189         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
9190         COUNT_BYTES(2);
9191
9192         /* queue elements */
9193         while(cnt--){
9194                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
9195                     &bc, &trunc);
9196                 if (trunc)
9197                         goto endofcommand;
9198         }
9199
9200         END_OF_SMB
9201
9202         return offset;
9203 }
9204
9205
9206 static int
9207 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9208 {
9209         int name_len;
9210         guint16 bc;
9211         guint8 wc;
9212         guint16 message_len;
9213
9214         WORD_COUNT;
9215
9216         BYTE_COUNT;
9217
9218         /* buffer format */
9219         CHECK_BYTE_COUNT(1);
9220         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9221         COUNT_BYTES(1);
9222
9223         /* originator name */
9224         /* XXX - what if this runs past bc? */
9225         name_len = tvb_strsize(tvb, offset);
9226         CHECK_BYTE_COUNT(name_len);
9227         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9228             name_len, TRUE);
9229         COUNT_BYTES(name_len);
9230
9231         /* buffer format */
9232         CHECK_BYTE_COUNT(1);
9233         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9234         COUNT_BYTES(1);
9235
9236         /* destination name */
9237         /* XXX - what if this runs past bc? */
9238         name_len = tvb_strsize(tvb, offset);
9239         CHECK_BYTE_COUNT(name_len);
9240         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9241             name_len, TRUE);
9242         COUNT_BYTES(name_len);
9243
9244         /* buffer format */
9245         CHECK_BYTE_COUNT(1);
9246         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9247         COUNT_BYTES(1);
9248
9249         /* message len */
9250         CHECK_BYTE_COUNT(2);
9251         message_len = tvb_get_letohs(tvb, offset);
9252         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9253             message_len);
9254         COUNT_BYTES(2);
9255
9256         /* message */
9257         CHECK_BYTE_COUNT(message_len);
9258         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9259             TRUE);
9260         COUNT_BYTES(message_len);
9261
9262         END_OF_SMB
9263
9264         return offset;
9265 }
9266
9267 static int
9268 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9269 {
9270         int name_len;
9271         guint16 bc;
9272         guint8 wc;
9273
9274         WORD_COUNT;
9275
9276         BYTE_COUNT;
9277
9278         /* buffer format */
9279         CHECK_BYTE_COUNT(1);
9280         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9281         COUNT_BYTES(1);
9282
9283         /* originator name */
9284         /* XXX - what if this runs past bc? */
9285         name_len = tvb_strsize(tvb, offset);
9286         CHECK_BYTE_COUNT(name_len);
9287         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9288             name_len, TRUE);
9289         COUNT_BYTES(name_len);
9290
9291         /* buffer format */
9292         CHECK_BYTE_COUNT(1);
9293         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9294         COUNT_BYTES(1);
9295
9296         /* destination name */
9297         /* XXX - what if this runs past bc? */
9298         name_len = tvb_strsize(tvb, offset);
9299         CHECK_BYTE_COUNT(name_len);
9300         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9301             name_len, TRUE);
9302         COUNT_BYTES(name_len);
9303
9304         END_OF_SMB
9305
9306         return offset;
9307 }
9308
9309 static int
9310 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9311 {
9312         guint16 bc;
9313         guint8 wc;
9314
9315         WORD_COUNT;
9316
9317         /* message group ID */
9318         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
9319         offset += 2;
9320
9321         BYTE_COUNT;
9322
9323         END_OF_SMB
9324
9325         return offset;
9326 }
9327
9328 static int
9329 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9330 {
9331         guint16 bc;
9332         guint8 wc;
9333         guint16 message_len;
9334
9335         WORD_COUNT;
9336
9337         BYTE_COUNT;
9338
9339         /* buffer format */
9340         CHECK_BYTE_COUNT(1);
9341         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9342         COUNT_BYTES(1);
9343
9344         /* message len */
9345         CHECK_BYTE_COUNT(2);
9346         message_len = tvb_get_letohs(tvb, offset);
9347         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9348             message_len);
9349         COUNT_BYTES(2);
9350
9351         /* message */
9352         CHECK_BYTE_COUNT(message_len);
9353         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9354             TRUE);
9355         COUNT_BYTES(message_len);
9356
9357         END_OF_SMB
9358
9359         return offset;
9360 }
9361
9362 static int
9363 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9364 {
9365         int name_len;
9366         guint16 bc;
9367         guint8 wc;
9368
9369         WORD_COUNT;
9370
9371         BYTE_COUNT;
9372
9373         /* buffer format */
9374         CHECK_BYTE_COUNT(1);
9375         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9376         COUNT_BYTES(1);
9377
9378         /* forwarded name */
9379         /* XXX - what if this runs past bc? */
9380         name_len = tvb_strsize(tvb, offset);
9381         CHECK_BYTE_COUNT(name_len);
9382         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
9383             name_len, TRUE);
9384         COUNT_BYTES(name_len);
9385
9386         END_OF_SMB
9387
9388         return offset;
9389 }
9390
9391 static int
9392 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9393 {
9394         int name_len;
9395         guint16 bc;
9396         guint8 wc;
9397
9398         WORD_COUNT;
9399
9400         BYTE_COUNT;
9401
9402         /* buffer format */
9403         CHECK_BYTE_COUNT(1);
9404         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9405         COUNT_BYTES(1);
9406
9407         /* machine name */
9408         /* XXX - what if this runs past bc? */
9409         name_len = tvb_strsize(tvb, offset);
9410         CHECK_BYTE_COUNT(name_len);
9411         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
9412             name_len, TRUE);
9413         COUNT_BYTES(name_len);
9414
9415         END_OF_SMB
9416
9417         return offset;
9418 }
9419
9420
9421 static int
9422 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9423 {
9424         guint8  wc, cmd=0xff;
9425         guint16 andxoffset=0;
9426         guint16 bc;
9427         smb_info_t *si = pinfo->private_data;
9428         int fn_len;
9429         const char *fn;
9430
9431         WORD_COUNT;
9432
9433         /* next smb command */
9434         cmd = tvb_get_guint8(tvb, offset);
9435         if(cmd!=0xff){
9436                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9437         } else {
9438                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9439         }
9440         offset += 1;
9441
9442         /* reserved byte */
9443         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9444         offset += 1;
9445
9446         /* andxoffset */
9447         andxoffset = tvb_get_letohs(tvb, offset);
9448         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9449         offset += 2;
9450
9451         /* reserved byte */
9452         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9453         offset += 1;
9454
9455         /* file name len */
9456         fn_len = tvb_get_letohs(tvb, offset);
9457         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
9458         offset += 2;
9459
9460         /* Create flags */
9461         offset = dissect_nt_create_bits(tvb, tree, offset);
9462
9463         /* root directory fid */
9464         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
9465         offset += 4;
9466
9467         /* nt access mask */
9468         offset = dissect_smb_access_mask(tvb, tree, offset);
9469
9470         /* allocation size */
9471         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9472         offset += 8;
9473
9474         /* Extended File Attributes */
9475         offset = dissect_file_ext_attr(tvb, tree, offset);
9476
9477         /* share access */
9478         offset = dissect_nt_share_access(tvb, tree, offset);
9479
9480         /* create disposition */
9481         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
9482         offset += 4;
9483
9484         /* create options */
9485         offset = dissect_nt_create_options(tvb, tree, offset);
9486
9487         /* impersonation level */
9488         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
9489         offset += 4;
9490
9491         /* security flags */
9492         offset = dissect_nt_security_flags(tvb, tree, offset);
9493
9494         BYTE_COUNT;
9495
9496         /* file name */
9497         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9498         if (fn == NULL)
9499                 goto endofcommand;
9500         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9501                 fn);
9502         COUNT_BYTES(fn_len);
9503
9504         if (check_col(pinfo->cinfo, COL_INFO)) {
9505                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
9506         }
9507
9508         END_OF_SMB
9509
9510         /* call AndXCommand (if there are any) */
9511         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9512
9513         return offset;
9514 }
9515
9516
9517 static int
9518 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9519 {
9520         guint8  wc, cmd=0xff;
9521         guint16 andxoffset=0;
9522         guint16 bc;
9523         guint16 fid;
9524
9525         WORD_COUNT;
9526
9527         /* next smb command */
9528         cmd = tvb_get_guint8(tvb, offset);
9529         if(cmd!=0xff){
9530                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9531         } else {
9532                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9533         }
9534         offset += 1;
9535
9536         /* reserved byte */
9537         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9538         offset += 1;
9539
9540         /* andxoffset */
9541         andxoffset = tvb_get_letohs(tvb, offset);
9542         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9543         offset += 2;
9544
9545         /* oplock level */
9546         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
9547         offset += 1;
9548
9549         /* fid */
9550         fid = tvb_get_letohs(tvb, offset);
9551         add_fid(tvb, pinfo, tree, offset, 2, fid);
9552         offset += 2;
9553
9554         /* create action */
9555         /*XXX is this really the same as create disposition in the request? it looks so*/
9556         /* No, it is not. It is the same as the create action from an Open&X request ... RJS */
9557         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
9558         offset += 4;
9559
9560         /* create time */
9561         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
9562
9563         /* access time */
9564         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
9565
9566         /* last write time */
9567         offset = dissect_smb_64bit_time(tvb, tree, offset,
9568                 hf_smb_last_write_time);
9569
9570         /* last change time */
9571         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
9572
9573         /* Extended File Attributes */
9574         offset = dissect_file_ext_attr(tvb, tree, offset);
9575
9576         /* allocation size */
9577         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9578         offset += 8;
9579
9580         /* end of file */
9581         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9582         offset += 8;
9583
9584         /* File Type */
9585         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
9586         offset += 2;
9587
9588         /* IPC State */
9589         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9590
9591         /* is directory */
9592         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9593         offset += 1;
9594
9595         BYTE_COUNT;
9596
9597         END_OF_SMB
9598
9599         /* call AndXCommand (if there are any) */
9600         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9601
9602         return offset;
9603 }
9604
9605
9606 static int
9607 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9608 {
9609         guint8 wc;
9610         guint16 bc;
9611
9612         WORD_COUNT;
9613
9614         BYTE_COUNT;
9615
9616         END_OF_SMB
9617
9618         return offset;
9619 }
9620
9621 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9622    BEGIN Transaction/Transaction2 Primary and secondary requests
9623    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9624
9625
9626 const value_string trans2_cmd_vals[] = {
9627         { 0x00,         "OPEN2" },
9628         { 0x01,         "FIND_FIRST2" },
9629         { 0x02,         "FIND_NEXT2" },
9630         { 0x03,         "QUERY_FS_INFO" },
9631         { 0x04,         "SET_FS_QUOTA" },
9632         { 0x05,         "QUERY_PATH_INFO" },
9633         { 0x06,         "SET_PATH_INFO" },
9634         { 0x07,         "QUERY_FILE_INFO" },
9635         { 0x08,         "SET_FILE_INFO" },
9636         { 0x09,         "FSCTL" },
9637         { 0x0A,         "IOCTL2" },
9638         { 0x0B,         "FIND_NOTIFY_FIRST" },
9639         { 0x0C,         "FIND_NOTIFY_NEXT" },
9640         { 0x0D,         "CREATE_DIRECTORY" },
9641         { 0x0E,         "SESSION_SETUP" },
9642         { 0x10,         "GET_DFS_REFERRAL" },
9643         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
9644         { 0,    NULL }
9645 };
9646
9647 static const true_false_string tfs_tf_dtid = {
9648         "Also DISCONNECT TID",
9649         "Do NOT disconnect TID"
9650 };
9651 static const true_false_string tfs_tf_owt = {
9652         "One Way Transaction (NO RESPONSE)",
9653         "Two way transaction"
9654 };
9655
9656 static const true_false_string tfs_ff2_backup = {
9657         "Find WITH backup intent",
9658         "No backup intent"
9659 };
9660 static const true_false_string tfs_ff2_continue = {
9661         "CONTINUE search from previous position",
9662         "New search, do NOT continue from previous position"
9663 };
9664 static const true_false_string tfs_ff2_resume = {
9665         "Return RESUME keys",
9666         "Do NOT return resume keys"
9667 };
9668 static const true_false_string tfs_ff2_close_eos = {
9669         "CLOSE search if END OF SEARCH is reached",
9670         "Do NOT close search if end of search reached"
9671 };
9672 static const true_false_string tfs_ff2_close = {
9673         "CLOSE search after this request",
9674         "Do NOT close search after this request"
9675 };
9676
9677 /* used by
9678    TRANS2_FIND_FIRST2
9679 */
9680 static const value_string ff2_il_vals[] = {
9681         { 1,            "Info Standard"},
9682         { 2,            "Info Query EA Size"},
9683         { 3,            "Info Query EAs From List"},
9684         { 0x0101,       "Find File Directory Info"},
9685         { 0x0102,       "Find File Full Directory Info"},
9686         { 0x0103,       "Find File Names Info"},
9687         { 0x0104,       "Find File Both Directory Info"},
9688         { 0x0202,       "Find File UNIX"},
9689         {0, NULL}
9690 };
9691
9692 /* values used by :
9693         TRANS2_QUERY_PATH_INFORMATION
9694         TRANS2_QUERY_FILE_INFORMATION
9695 */
9696 static const value_string qpi_loi_vals[] = {
9697         { 1,            "Info Standard"},
9698         { 2,            "Info Query EA Size"},
9699         { 3,            "Info Query EAs From List"},
9700         { 4,            "Info Query All EAs"},
9701         { 6,            "Info Is Name Valid"},
9702         { 0x0101,       "Query File Basic Info"},
9703         { 0x0102,       "Query File Standard Info"},
9704         { 0x0103,       "Query File EA Info"},
9705         { 0x0104,       "Query File Name Info"},
9706         { 0x0107,       "Query File All Info"},
9707         { 0x0108,       "Query File Alt Name Info"},
9708         { 0x0109,       "Query File Stream Info"},
9709         { 0x010b,       "Query File Compression Info"},
9710         { 0x0200,       "Query File Unix Basic"},
9711         { 0x0201,       "Query File Unix Link"},
9712         { 1004,         "Query File Basic Info"},
9713         { 1005,         "Query File Standard Info"},
9714         { 1006,         "Query File Internal Info"},
9715         { 1007,         "Query File EA Info"},
9716         { 1009,         "Query File Name Info"},
9717         { 1010,         "Query File Rename Info"},
9718         { 1011,         "Query File Link Info"},
9719         { 1012,         "Query File Names Info"},
9720         { 1013,         "Query File Disposition Info"},
9721         { 1014,         "Query File Position Info"},
9722         { 1015,         "Query File Full EA Info"},
9723         { 1016,         "Query File Mode Info"},
9724         { 1017,         "Query File Alignment Info"},
9725         { 1018,         "Query File All Info"},
9726         { 1019,         "Query File Allocation Info"},
9727         { 1020,         "Query File End of File Info"},
9728         { 1021,         "Query File Alt Name Info"},
9729         { 1022,         "Query File Stream Info"},
9730         { 1023,         "Query File Pipe Info"},
9731         { 1024,         "Query File Pipe Local Info"},
9732         { 1025,         "Query File Pipe Remote Info"},
9733         { 1026,         "Query File Mailslot Query Info"},
9734         { 1027,         "Query File Mailslot Set Info"},
9735         { 1028,         "Query File Compression Info"},
9736         { 1029,         "Query File ObjectID Info"},
9737         { 1030,         "Query File Completion Info"},
9738         { 1031,         "Query File Move Cluster Info"},
9739         { 1032,         "Query File Quota Info"},
9740         { 1033,         "Query File Reparsepoint Info"},
9741         { 1034,         "Query File Network Open Info"},
9742         { 1035,         "Query File Attribute Tag Info"},
9743         { 1036,         "Query File Tracking Info"},
9744         { 1037,         "Query File Maximum Info"},
9745         {0, NULL}
9746 };
9747
9748 /* values used by :
9749         TRANS2_SET_PATH_INFORMATION
9750         TRANS2_SET_FILE_INFORMATION
9751         (the SNIA CIFS spec lists some only for TRANS2_SET_FILE_INFORMATION,
9752         but I'm assuming they apply to TRANS2_SET_PATH_INFORMATION as
9753         well; note that they're different from the QUERY_PATH_INFORMATION
9754         and QUERY_FILE_INFORMATION values!)
9755 */
9756 static const value_string spi_loi_vals[] = {
9757         { 1,            "Info Standard"},
9758         { 2,            "Info Query EA Size"},
9759         { 4,            "Info Query All EAs"},
9760         { 0x0101,       "Set File Basic Info"},
9761         { 0x0102,       "Set File Disposition Info"},
9762         { 0x0103,       "Set File Allocation Info"},
9763         { 0x0104,       "Set File End Of File Info"},
9764         { 0x0200,       "Set File Unix Basic"},
9765         { 0x0201,       "Set File Unix Link"},
9766         { 0x0202,       "Set File Unix HardLink"},
9767         { 1004,         "Set File Basic Info"},
9768         { 1010,         "Set Rename Information"},
9769         { 1013,         "Set Disposition Information"},
9770         { 1014,         "Set Position Information"},
9771         { 1016,         "Set Mode Information"},
9772         { 1019,         "Set Allocation Information"},
9773         { 1020,         "Set EOF Information"},
9774         { 1023,         "Set File Pipe Information"},
9775         { 1025,         "Set File Pipe Remote Information"},
9776         { 1029,         "Set Copy On Write Information"},
9777         { 1032,         "Set OLE Class ID Information"},
9778         { 1039,         "Set Inherit Context Index Information"},
9779         { 1040,         "Set OLE Information (?)"},
9780         {0, NULL}
9781 };
9782
9783 static const value_string qfsi_vals[] = {
9784         { 1,            "Info Allocation"},
9785         { 2,            "Info Volume"},
9786         { 0x0101,       "Query FS Label Info"},
9787         { 0x0102,       "Query FS Volume Info"},
9788         { 0x0103,       "Query FS Size Info"},
9789         { 0x0104,       "Query FS Device Info"},
9790         { 0x0105,       "Query FS Attribute Info"},
9791         { 0x0200,       "Unix Query FS Info"},
9792         { 0x0301,       "Mac Query FS Info"},
9793         { 1001,         "Query FS Label Info"},
9794         { 1002,         "Query FS Volume Info"},
9795         { 1003,         "Query FS Size Info"},
9796         { 1004,         "Query FS Device Info"},
9797         { 1005,         "Query FS Attribute Info"},
9798         { 1006,         "Query FS Quota Info"},
9799         { 1007,         "Query Full FS Size Info"},
9800         { 1008,         "Object ID Information"},
9801         {0, NULL}
9802 };
9803
9804 static const value_string nt_rename_vals[] = {
9805         { 0x0103,       "Create Hard Link"},
9806         {0, NULL}
9807 };
9808
9809
9810 static const value_string delete_pending_vals[] = {
9811         {0,     "Normal, no pending delete"},
9812         {1,     "This object has DELETE PENDING"},
9813         {0, NULL}
9814 };
9815
9816 static const value_string alignment_vals[] = {
9817         {0,     "Byte alignment"},
9818         {1,     "Word (16bit) alignment"},
9819         {3,     "Long (32bit) alignment"},
9820         {7,     "8 byte boundary alignment"},
9821         {0x0f,  "16 byte boundary alignment"},
9822         {0x1f,  "32 byte boundary alignment"},
9823         {0x3f,  "64 byte boundary alignment"},
9824         {0x7f,  "128 byte boundary alignment"},
9825         {0xff,  "256 byte boundary alignment"},
9826         {0x1ff, "512 byte boundary alignment"},
9827         {0, NULL}
9828 };
9829
9830 static const true_false_string tfs_marked_for_deletion = {
9831         "File is MARKED FOR DELETION",
9832         "File is NOT marked for deletion"
9833 };
9834
9835 static const true_false_string tfs_get_dfs_server_hold_storage = {
9836         "Referral SERVER HOLDS STORAGE for the file",
9837         "Referral server does NOT hold storage for the file"
9838 };
9839 static const true_false_string tfs_get_dfs_fielding = {
9840         "The server in referral is FIELDING CAPABLE",
9841         "The server in referrals is NOT fielding capable"
9842 };
9843
9844 static const true_false_string tfs_dfs_referral_flags_strip = {
9845         "STRIP off pathconsumed characters before submitting",
9846         "Do NOT strip off any characters"
9847 };
9848
9849 static const value_string dfs_referral_server_type_vals[] = {
9850         {0,     "Don't know"},
9851         {1,     "SMB Server"},
9852         {2,     "Netware Server"},
9853         {3,     "Domain Server"},
9854         {0, NULL}
9855 };
9856
9857
9858 static const true_false_string tfs_device_char_removable = {
9859         "This is a REMOVABLE device",
9860         "This is NOT a removable device"
9861 };
9862 static const true_false_string tfs_device_char_read_only = {
9863         "This is a READ-ONLY device",
9864         "This is NOT a read-only device"
9865 };
9866 static const true_false_string tfs_device_char_floppy = {
9867         "This is a FLOPPY DISK device",
9868         "This is NOT a floppy disk device"
9869 };
9870 static const true_false_string tfs_device_char_write_once = {
9871         "This is a WRITE-ONCE device",
9872         "This is NOT a write-once device"
9873 };
9874 static const true_false_string tfs_device_char_remote = {
9875         "This is a REMOTE device",
9876         "This is NOT a remote device"
9877 };
9878 static const true_false_string tfs_device_char_mounted = {
9879         "This device is MOUNTED",
9880         "This device is NOT mounted"
9881 };
9882 static const true_false_string tfs_device_char_virtual = {
9883         "This is a VIRTUAL device",
9884         "This is NOT a virtual device"
9885 };
9886
9887
9888 static const true_false_string tfs_fs_attr_css = {
9889         "This FS supports CASE SENSITIVE SEARCHes",
9890         "This FS does NOT support case sensitive searches"
9891 };
9892 static const true_false_string tfs_fs_attr_cpn = {
9893         "This FS supports CASE PRESERVED NAMES",
9894         "This FS does NOT support case preserved names"
9895 };
9896 static const true_false_string tfs_fs_attr_pacls = {
9897         "This FS supports PERSISTENT ACLs",
9898         "This FS does NOT support persistent acls"
9899 };
9900 static const true_false_string tfs_fs_attr_fc = {
9901         "This FS supports COMPRESSED FILES",
9902         "This FS does NOT support compressed files"
9903 };
9904 static const true_false_string tfs_fs_attr_vq = {
9905         "This FS supports VOLUME QUOTAS",
9906         "This FS does NOT support volume quotas"
9907 };
9908 static const true_false_string tfs_fs_attr_dim = {
9909         "This FS is on a MOUNTED DEVICE",
9910         "This FS is NOT on a mounted device"
9911 };
9912 static const true_false_string tfs_fs_attr_vic = {
9913         "This FS is on a COMPRESSED VOLUME",
9914         "This FS is NOT on a compressed volume"
9915 };
9916
9917 #define FF2_RESUME      0x0004
9918
9919 static int
9920 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9921 {
9922         guint16 mask;
9923         proto_item *item = NULL;
9924         proto_tree *tree = NULL;
9925         smb_info_t *si;
9926         smb_transact2_info_t *t2i;
9927
9928         mask = tvb_get_letohs(tvb, offset);
9929
9930         si = (smb_info_t *)pinfo->private_data;
9931         if (si->sip != NULL) {
9932                 t2i = si->sip->extra_info;
9933                 if (t2i != NULL) {
9934                         if (!pinfo->fd->flags.visited)
9935                                 t2i->resume_keys = (mask & FF2_RESUME);
9936                 }
9937         }
9938
9939         if(parent_tree){
9940                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9941                         "Flags: 0x%04x", mask);
9942                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
9943         }
9944
9945         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
9946                 tvb, offset, 2, mask);
9947         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
9948                 tvb, offset, 2, mask);
9949         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
9950                 tvb, offset, 2, mask);
9951         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
9952                 tvb, offset, 2, mask);
9953         proto_tree_add_boolean(tree, hf_smb_ff2_close,
9954                 tvb, offset, 2, mask);
9955
9956         offset += 2;
9957
9958         return offset;
9959 }
9960
9961 #if 0
9962 static int
9963 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9964 {
9965         guint16 mask;
9966         proto_item *item = NULL;
9967         proto_tree *tree = NULL;
9968
9969         mask = tvb_get_letohs(tvb, offset);
9970
9971         if(parent_tree){
9972                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9973                         "IO Flag: 0x%04x", mask);
9974                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
9975         }
9976
9977         proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
9978                 tvb, offset, 2, mask);
9979         proto_tree_add_boolean(tree, hf_smb_sfi_caching,
9980                 tvb, offset, 2, mask);
9981
9982         offset += 2;
9983
9984         return offset;
9985 }
9986 #endif
9987
9988 static int
9989 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
9990     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
9991 {
9992         proto_item *item = NULL;
9993         proto_tree *tree = NULL;
9994         smb_info_t *si;
9995         smb_transact2_info_t *t2i;
9996         int fn_len;
9997         const char *fn;
9998
9999         si = (smb_info_t *)pinfo->private_data;
10000         if (si->sip != NULL)
10001                 t2i = si->sip->extra_info;
10002         else
10003                 t2i = NULL;
10004
10005         if(parent_tree){
10006                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
10007                                 "%s Parameters",
10008                                 val_to_str(subcmd, trans2_cmd_vals,
10009                                            "Unknown (0x%02x)"));
10010                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
10011         }
10012
10013         switch(subcmd){
10014         case 0x00:      /*TRANS2_OPEN2*/
10015                 /* open flags */
10016                 CHECK_BYTE_COUNT_TRANS(2);
10017                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
10018                 bc -= 2;
10019
10020                 /* desired access */
10021                 CHECK_BYTE_COUNT_TRANS(2);
10022                 offset = dissect_access(tvb, tree, offset, "Desired");
10023                 bc -= 2;
10024
10025                 /* Search Attributes */
10026                 CHECK_BYTE_COUNT_TRANS(2);
10027                 offset = dissect_search_attributes(tvb, tree, offset);
10028                 bc -= 2;
10029
10030                 /* File Attributes */
10031                 CHECK_BYTE_COUNT_TRANS(2);
10032                 offset = dissect_file_attributes(tvb, tree, offset, 2);
10033                 bc -= 2;
10034
10035                 /* create time */
10036                 CHECK_BYTE_COUNT_TRANS(4);
10037                 offset = dissect_smb_datetime(tvb, tree, offset,
10038                         hf_smb_create_time,
10039                         hf_smb_create_dos_date, hf_smb_create_dos_time,
10040                         TRUE);
10041                 bc -= 4;
10042
10043                 /* open function */
10044                 CHECK_BYTE_COUNT_TRANS(2);
10045                 offset = dissect_open_function(tvb, tree, offset);
10046                 bc -= 2;
10047
10048                 /* allocation size */
10049                 CHECK_BYTE_COUNT_TRANS(4);
10050                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10051                 COUNT_BYTES_TRANS(4);
10052
10053                 /* 10 reserved bytes */
10054                 CHECK_BYTE_COUNT_TRANS(10);
10055                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
10056                 COUNT_BYTES_TRANS(10);
10057
10058                 /* file name */
10059                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10060                 CHECK_STRING_TRANS(fn);
10061                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10062                         fn);
10063                 COUNT_BYTES_TRANS(fn_len);
10064
10065                 if (check_col(pinfo->cinfo, COL_INFO)) {
10066                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10067                         fn);
10068                 }
10069                 break;
10070         case 0x01:      /*TRANS2_FIND_FIRST2*/
10071                 /* Search Attributes */
10072                 CHECK_BYTE_COUNT_TRANS(2);
10073                 offset = dissect_search_attributes(tvb, tree, offset);
10074                 bc -= 2;
10075
10076                 /* search count */
10077                 CHECK_BYTE_COUNT_TRANS(2);
10078                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10079                 COUNT_BYTES_TRANS(2);
10080
10081                 /* Find First2 flags */
10082                 CHECK_BYTE_COUNT_TRANS(2);
10083                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10084                 bc -= 2;
10085
10086                 /* Find First2 information level */
10087                 CHECK_BYTE_COUNT_TRANS(2);
10088                 si->info_level = tvb_get_letohs(tvb, offset);
10089                 if (!pinfo->fd->flags.visited)
10090                         t2i->info_level = si->info_level;
10091                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10092                 COUNT_BYTES_TRANS(2);
10093
10094                 /* storage type */
10095                 CHECK_BYTE_COUNT_TRANS(4);
10096                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
10097                 COUNT_BYTES_TRANS(4);
10098
10099                 /* search pattern */
10100                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10101                 CHECK_STRING_TRANS(fn);
10102                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
10103                         fn);
10104                 COUNT_BYTES_TRANS(fn_len);
10105
10106                 if (check_col(pinfo->cinfo, COL_INFO)) {
10107                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
10108                         fn);
10109                 }
10110
10111                 break;
10112         case 0x02:      /*TRANS2_FIND_NEXT2*/
10113                 /* sid */
10114                 CHECK_BYTE_COUNT_TRANS(2);
10115                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
10116                 COUNT_BYTES_TRANS(2);
10117
10118                 /* search count */
10119                 CHECK_BYTE_COUNT_TRANS(2);
10120                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10121                 COUNT_BYTES_TRANS(2);
10122
10123                 /* Find First2 information level */
10124                 CHECK_BYTE_COUNT_TRANS(2);
10125                 si->info_level = tvb_get_letohs(tvb, offset);
10126                 if (!pinfo->fd->flags.visited)
10127                         t2i->info_level = si->info_level;
10128                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10129                 COUNT_BYTES_TRANS(2);
10130
10131                 /* resume key */
10132                 CHECK_BYTE_COUNT_TRANS(4);
10133                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
10134                 COUNT_BYTES_TRANS(4);
10135
10136                 /* Find First2 flags */
10137                 CHECK_BYTE_COUNT_TRANS(2);
10138                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10139                 bc -= 2;
10140
10141                 /* file name */
10142                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10143                 CHECK_STRING_TRANS(fn);
10144                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10145                         fn);
10146                 COUNT_BYTES_TRANS(fn_len);
10147
10148                 if (check_col(pinfo->cinfo, COL_INFO)) {
10149                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
10150                         fn);
10151                 }
10152
10153                 break;
10154         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10155                 /* level of interest */
10156                 CHECK_BYTE_COUNT_TRANS(2);
10157                 si->info_level = tvb_get_letohs(tvb, offset);
10158                 if (!pinfo->fd->flags.visited)
10159                         t2i->info_level = si->info_level;
10160                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
10161                 COUNT_BYTES_TRANS(2);
10162
10163                 if (check_col(pinfo->cinfo, COL_INFO))
10164                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
10165                                         val_to_str(si->info_level, qfsi_vals, 
10166                                                    "Unknown (0x%02x)"));
10167
10168                 break;
10169         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10170                 /* level of interest */
10171                 CHECK_BYTE_COUNT_TRANS(2);
10172                 si->info_level = tvb_get_letohs(tvb, offset);
10173                 if (!pinfo->fd->flags.visited)
10174                         t2i->info_level = si->info_level;
10175                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10176                 COUNT_BYTES_TRANS(2);
10177
10178                 if (check_col(pinfo->cinfo, COL_INFO)) {
10179                         col_append_fstr(
10180                                 pinfo->cinfo, COL_INFO, ", %s", 
10181                                 val_to_str(si->info_level, qpi_loi_vals, 
10182                                            "Unknown (%u)"));
10183                 }
10184
10185                 /* 4 reserved bytes */
10186                 CHECK_BYTE_COUNT_TRANS(4);
10187                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10188                 COUNT_BYTES_TRANS(4);
10189
10190                 /* file name */
10191                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10192                 CHECK_STRING_TRANS(fn);
10193                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10194                         fn);
10195                 COUNT_BYTES_TRANS(fn_len);
10196
10197                 if (check_col(pinfo->cinfo, COL_INFO)) {
10198                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10199                         fn);
10200                 }
10201
10202                 break;
10203         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10204                 /* level of interest */
10205                 CHECK_BYTE_COUNT_TRANS(2);
10206                 si->info_level = tvb_get_letohs(tvb, offset);
10207                 if (!pinfo->fd->flags.visited)
10208                         t2i->info_level = si->info_level;
10209                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10210                 COUNT_BYTES_TRANS(2);
10211
10212                 /* 4 reserved bytes */
10213                 CHECK_BYTE_COUNT_TRANS(4);
10214                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10215                 COUNT_BYTES_TRANS(4);
10216
10217                 /* file name */
10218                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10219                 CHECK_STRING_TRANS(fn);
10220                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10221                         fn);
10222                 COUNT_BYTES_TRANS(fn_len);
10223
10224                 if (check_col(pinfo->cinfo, COL_INFO)) {
10225                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10226                         fn);
10227                 }
10228
10229                 break;
10230         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
10231                 guint16 fid;
10232
10233                 /* fid */
10234                 CHECK_BYTE_COUNT_TRANS(2);
10235                 fid = tvb_get_letohs(tvb, offset);
10236                 add_fid(tvb, pinfo, tree, offset, 2, fid);
10237                 COUNT_BYTES_TRANS(2);
10238
10239                 /* level of interest */
10240                 CHECK_BYTE_COUNT_TRANS(2);
10241                 si->info_level = tvb_get_letohs(tvb, offset);
10242                 if (!pinfo->fd->flags.visited)
10243                         t2i->info_level = si->info_level;
10244                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10245                 COUNT_BYTES_TRANS(2);
10246
10247                 if (check_col(pinfo->cinfo, COL_INFO)) {
10248                         col_append_fstr(
10249                                 pinfo->cinfo, COL_INFO, ", %s", 
10250                                 val_to_str(si->info_level, qpi_loi_vals, 
10251                                            "Unknown (%u)"));
10252                 }
10253
10254                 break;
10255         }
10256         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
10257                 guint16 fid;
10258
10259                 /* fid */
10260                 CHECK_BYTE_COUNT_TRANS(2);
10261                 fid = tvb_get_letohs(tvb, offset);
10262                 add_fid(tvb, pinfo, tree, offset, 2, fid);
10263                 COUNT_BYTES_TRANS(2);
10264
10265                 /* level of interest */
10266                 CHECK_BYTE_COUNT_TRANS(2);
10267                 si->info_level = tvb_get_letohs(tvb, offset);
10268                 if (!pinfo->fd->flags.visited)
10269                         t2i->info_level = si->info_level;
10270                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10271                 COUNT_BYTES_TRANS(2);
10272
10273 #if 0
10274                 /*
10275                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10276                  * Extensions Version 3.0, Document Version 1.11,
10277                  * July 19, 1990" says this is I/O flags, but it's
10278                  * reserved in the SNIA spec, and some clients appear
10279                  * to leave junk in it.
10280                  *
10281                  * Is this some field used only if a particular
10282                  * dialect was negotiated, so that clients can feel
10283                  * safe not setting it if they haven't negotiated that
10284                  * dialect?  Or do the (non-OS/2) clients simply not care
10285                  * about that particular OS/2-oriented dialect?
10286                  */
10287
10288                 /* IO Flag */
10289                 CHECK_BYTE_COUNT_TRANS(2);
10290                 offset = dissect_sfi_ioflag(tvb, tree, offset);
10291                 bc -= 2;
10292 #else
10293                 /* 2 reserved bytes */
10294                 CHECK_BYTE_COUNT_TRANS(2);
10295                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10296                 COUNT_BYTES_TRANS(2);
10297 #endif
10298
10299                 break;
10300         }
10301         case 0x09:      /*TRANS2_FSCTL*/
10302                 /* this call has no parameter block in the request */
10303
10304                 /*
10305                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10306                  * Extensions Version 3.0, Document Version 1.11,
10307                  * July 19, 1990" says this this contains a
10308                  * "File system specific parameter block".  (That means
10309                  * we may not be able to dissect it in any case.)
10310                  */
10311                 break;
10312         case 0x0a:      /*TRANS2_IOCTL2*/
10313                 /* this call has no parameter block in the request */
10314
10315                 /*
10316                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10317                  * Extensions Version 3.0, Document Version 1.11,
10318                  * July 19, 1990" says this this contains a
10319                  * "Device/function specific parameter block".  (That
10320                  * means we may not be able to dissect it in any case.)
10321                  */
10322                 break;
10323         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
10324                 /* Search Attributes */
10325                 CHECK_BYTE_COUNT_TRANS(2);
10326                 offset = dissect_search_attributes(tvb, tree, offset);
10327                 bc -= 2;
10328
10329                 /* Number of changes to wait for */
10330                 CHECK_BYTE_COUNT_TRANS(2);
10331                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10332                 COUNT_BYTES_TRANS(2);
10333
10334                 /* Find Notify information level */
10335                 CHECK_BYTE_COUNT_TRANS(2);
10336                 si->info_level = tvb_get_letohs(tvb, offset);
10337                 if (!pinfo->fd->flags.visited)
10338                         t2i->info_level = si->info_level;
10339                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
10340                 COUNT_BYTES_TRANS(2);
10341
10342                 /* 4 reserved bytes */
10343                 CHECK_BYTE_COUNT_TRANS(4);
10344                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10345                 COUNT_BYTES_TRANS(4);
10346
10347                 /* file name */
10348                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10349                 CHECK_STRING_TRANS(fn);
10350                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10351                         fn);
10352                 COUNT_BYTES_TRANS(fn_len);
10353
10354                 if (check_col(pinfo->cinfo, COL_INFO)) {
10355                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10356                         fn);
10357                 }
10358
10359                 break;
10360         }
10361         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
10362                 /* Monitor handle */
10363                 CHECK_BYTE_COUNT_TRANS(2);
10364                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
10365                 COUNT_BYTES_TRANS(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                 break;
10373         }
10374         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10375                 /* 4 reserved bytes */
10376                 CHECK_BYTE_COUNT_TRANS(4);
10377                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10378                 COUNT_BYTES_TRANS(4);
10379
10380                 /* dir name */
10381                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
10382                         FALSE, FALSE, &bc);
10383                 CHECK_STRING_TRANS(fn);
10384                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
10385                         fn);
10386                 COUNT_BYTES_TRANS(fn_len);
10387
10388                 if (check_col(pinfo->cinfo, COL_INFO)) {
10389                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
10390                         fn);
10391                 }
10392                 break;
10393         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10394                 /* XXX unknown structure*/
10395                 break;
10396         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10397                 /* referral level */
10398                 CHECK_BYTE_COUNT_TRANS(2);
10399                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
10400                 COUNT_BYTES_TRANS(2);
10401
10402                 /* file name */
10403                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10404                 CHECK_STRING_TRANS(fn);
10405                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10406                         fn);
10407                 COUNT_BYTES_TRANS(fn_len);
10408
10409                 if (check_col(pinfo->cinfo, COL_INFO)) {
10410                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10411                         fn);
10412                 }
10413
10414                 break;
10415         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10416                 /* file name */
10417                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10418                 CHECK_STRING_TRANS(fn);
10419                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10420                         fn);
10421                 COUNT_BYTES_TRANS(fn_len);
10422
10423                 if (check_col(pinfo->cinfo, COL_INFO)) {
10424                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10425                         fn);
10426                 }
10427
10428                 break;
10429         }
10430
10431         /* ooops there were data we didnt know how to process */
10432         if(bc != 0){
10433                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, bc, TRUE);
10434                 offset += bc;
10435         }
10436
10437         return offset;
10438 }
10439
10440 /*
10441  * XXX - just use "dissect_connect_flags()" here?
10442  */
10443 static guint16
10444 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10445 {
10446         guint16 mask;
10447         proto_item *item = NULL;
10448         proto_tree *tree = NULL;
10449
10450         mask = tvb_get_letohs(tvb, offset);
10451
10452         if(parent_tree){
10453                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10454                         "Flags: 0x%04x", mask);
10455                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
10456         }
10457
10458         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
10459                 tvb, offset, 2, mask);
10460         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
10461                 tvb, offset, 2, mask);
10462
10463         return mask;
10464 }
10465
10466
10467 static int
10468 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10469 {
10470         guint16 mask;
10471         proto_item *item = NULL;
10472         proto_tree *tree = NULL;
10473
10474         mask = tvb_get_letohs(tvb, offset);
10475
10476         if(parent_tree){
10477                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10478                         "Flags: 0x%04x", mask);
10479                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
10480         }
10481
10482         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
10483                 tvb, offset, 2, mask);
10484         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
10485                 tvb, offset, 2, mask);
10486
10487         offset += 2;
10488         return offset;
10489 }
10490
10491 static int
10492 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10493 {
10494         guint16 mask;
10495         proto_item *item = NULL;
10496         proto_tree *tree = NULL;
10497
10498         mask = tvb_get_letohs(tvb, offset);
10499
10500         if(parent_tree){
10501                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10502                         "Flags: 0x%04x", mask);
10503                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
10504         }
10505
10506         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
10507                 tvb, offset, 2, mask);
10508
10509         offset += 2;
10510
10511         return offset;
10512 }
10513
10514
10515 /* dfs inconsistency data  (4.4.2)
10516 */
10517 static int
10518 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
10519     proto_tree *tree, int offset, guint16 *bcp)
10520 {
10521         smb_info_t *si = pinfo->private_data;
10522         int fn_len;
10523         const char *fn;
10524
10525         /*XXX shouldn this data hold version and size? unclear from doc*/
10526         /* referral version */
10527         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10528         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
10529         COUNT_BYTES_TRANS_SUBR(2);
10530
10531         /* referral size */
10532         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10533         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
10534         COUNT_BYTES_TRANS_SUBR(2);
10535
10536         /* referral server type */
10537         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10538         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10539         COUNT_BYTES_TRANS_SUBR(2);
10540
10541         /* referral flags */
10542         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10543         offset = dissect_dfs_referral_flags(tvb, tree, offset);
10544         *bcp -= 2;
10545
10546         /* node name */
10547         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10548         CHECK_STRING_TRANS_SUBR(fn);
10549         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10550                 fn);
10551         COUNT_BYTES_TRANS_SUBR(fn_len);
10552
10553         return offset;
10554 }
10555
10556 /* get dfs referral data  (4.4.1)
10557 */
10558 static int
10559 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
10560     proto_tree *tree, int offset, guint16 *bcp)
10561 {
10562         smb_info_t *si = pinfo->private_data;
10563         guint16 numref;
10564         guint16 refsize;
10565         guint16 pathoffset;
10566         guint16 altpathoffset;
10567         guint16 nodeoffset;
10568         int fn_len;
10569         int stroffset;
10570         int offsetoffset;
10571         guint16 save_bc;
10572         const char *fn;
10573         int unklen;
10574         int ucstring_end;
10575         int ucstring_len;
10576
10577         /* path consumed */
10578         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10579         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
10580         COUNT_BYTES_TRANS_SUBR(2);
10581
10582         /* num referrals */
10583         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10584         numref = tvb_get_letohs(tvb, offset);
10585         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
10586         COUNT_BYTES_TRANS_SUBR(2);
10587
10588         /* get dfs flags */
10589         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10590         offset = dissect_get_dfs_flags(tvb, tree, offset);
10591         *bcp -= 2;
10592
10593         /* XXX - in at least one capture there appears to be 2 bytes
10594            of stuff after the Dfs flags, perhaps so that the header
10595            in front of the referral list is a multiple of 4 bytes long. */
10596         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10597         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
10598         COUNT_BYTES_TRANS_SUBR(2);
10599
10600         /* if there are any referrals */
10601         if(numref){
10602                 proto_item *ref_item = NULL;
10603                 proto_tree *ref_tree = NULL;
10604                 int old_offset=offset;
10605
10606                 if(tree){
10607                         ref_item = proto_tree_add_text(tree,
10608                                 tvb, offset, *bcp, "Referrals");
10609                         ref_tree = proto_item_add_subtree(ref_item,
10610                                 ett_smb_dfs_referrals);
10611                 }
10612                 ucstring_end = -1;
10613
10614                 while(numref--){
10615                         proto_item *ri = NULL;
10616                         proto_tree *rt = NULL;
10617                         int old_offset=offset;
10618                         guint16 version;
10619
10620                         if(tree){
10621                                 ri = proto_tree_add_text(ref_tree,
10622                                         tvb, offset, *bcp, "Referral");
10623                                 rt = proto_item_add_subtree(ri,
10624                                         ett_smb_dfs_referral);
10625                         }
10626
10627                         /* referral version */
10628                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10629                         version = tvb_get_letohs(tvb, offset);
10630                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
10631                                 tvb, offset, 2, version);
10632                         COUNT_BYTES_TRANS_SUBR(2);
10633
10634                         /* referral size */
10635                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10636                         refsize = tvb_get_letohs(tvb, offset);
10637                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
10638                         COUNT_BYTES_TRANS_SUBR(2);
10639
10640                         /* referral server type */
10641                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10642                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10643                         COUNT_BYTES_TRANS_SUBR(2);
10644
10645                         /* referral flags */
10646                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10647                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
10648                         *bcp -= 2;
10649
10650                         switch(version){
10651
10652                         case 1:
10653                                 /* node name */
10654                                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10655                                 CHECK_STRING_TRANS_SUBR(fn);
10656                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10657                                         fn);
10658                                 COUNT_BYTES_TRANS_SUBR(fn_len);
10659                                 break;
10660
10661                         case 2:
10662                         case 3: /* XXX - like version 2, but not identical;
10663                                    seen in a capture, but the format isn't
10664                                    documented */
10665                                 /* proximity */
10666                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10667                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
10668                                 COUNT_BYTES_TRANS_SUBR(2);
10669
10670                                 /* ttl */
10671                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10672                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
10673                                 COUNT_BYTES_TRANS_SUBR(2);
10674
10675                                 /* path offset */
10676                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10677                                 pathoffset = tvb_get_letohs(tvb, offset);
10678                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
10679                                 COUNT_BYTES_TRANS_SUBR(2);
10680
10681                                 /* alt path offset */
10682                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10683                                 altpathoffset = tvb_get_letohs(tvb, offset);
10684                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
10685                                 COUNT_BYTES_TRANS_SUBR(2);
10686
10687                                 /* node offset */
10688                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10689                                 nodeoffset = tvb_get_letohs(tvb, offset);
10690                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
10691                                 COUNT_BYTES_TRANS_SUBR(2);
10692
10693                                 /* path */
10694                                 if (pathoffset != 0) {
10695                                         stroffset = old_offset + pathoffset;
10696                                         offsetoffset = stroffset - offset;
10697                                         if (offsetoffset > 0 &&
10698                                             *bcp > offsetoffset) {
10699                                                 save_bc = *bcp;
10700                                                 *bcp -= offsetoffset;
10701                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10702                                                 CHECK_STRING_TRANS_SUBR(fn);
10703                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
10704                                                         fn);
10705                                                 stroffset += fn_len;
10706                                                 if (ucstring_end < stroffset)
10707                                                         ucstring_end = stroffset;
10708                                                 *bcp = save_bc;
10709                                         }
10710                                 }
10711
10712                                 /* alt path */
10713                                 if (altpathoffset != 0) {
10714                                         stroffset = old_offset + altpathoffset;
10715                                         offsetoffset = stroffset - offset;
10716                                         if (offsetoffset > 0 &&
10717                                             *bcp > offsetoffset) {
10718                                                 save_bc = *bcp;
10719                                                 *bcp -= offsetoffset;
10720                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10721                                                 CHECK_STRING_TRANS_SUBR(fn);
10722                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
10723                                                         fn);
10724                                                 stroffset += fn_len;
10725                                                 if (ucstring_end < stroffset)
10726                                                         ucstring_end = stroffset;
10727                                                 *bcp = save_bc;
10728                                         }
10729                                 }
10730
10731                                 /* node */
10732                                 if (nodeoffset != 0) {
10733                                         stroffset = old_offset + nodeoffset;
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_node, 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                                 break;
10750                         }
10751
10752                         /*
10753                          * Show anything beyond the length of the referral
10754                          * as unknown data.
10755                          */
10756                         unklen = (old_offset + refsize) - offset;
10757                         if (unklen < 0) {
10758                                 /*
10759                                  * XXX - the length is bogus.
10760                                  */
10761                                 unklen = 0;
10762                         }
10763                         if (unklen != 0) {
10764                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
10765                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
10766                                     offset, unklen, TRUE);
10767                                 COUNT_BYTES_TRANS_SUBR(unklen);
10768                         }
10769
10770                         proto_item_set_len(ri, offset-old_offset);
10771                 }
10772
10773                 /*
10774                  * Treat the offset past the end of the last Unicode
10775                  * string after the referrals (if any) as the last
10776                  * offset.
10777                  */
10778                 if (ucstring_end > offset) {
10779                         ucstring_len = ucstring_end - offset;
10780                         if (*bcp < ucstring_len)
10781                                 ucstring_len = *bcp;
10782                         offset += ucstring_len;
10783                         *bcp -= ucstring_len;
10784                 }
10785                 proto_item_set_len(ref_item, offset-old_offset);
10786         }
10787
10788         return offset;
10789 }
10790
10791
10792 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
10793    as described in 4.2.16.1
10794 */
10795 static int
10796 dissect_4_2_16_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10797     int offset, guint16 *bcp, gboolean *trunc)
10798 {
10799         /* create time */
10800         CHECK_BYTE_COUNT_SUBR(4);
10801         offset = dissect_smb_datetime(tvb, tree, offset,
10802                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
10803                 FALSE);
10804         *bcp -= 4;
10805
10806         /* access time */
10807         CHECK_BYTE_COUNT_SUBR(4);
10808         offset = dissect_smb_datetime(tvb, tree, offset,
10809                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
10810                 FALSE);
10811         *bcp -= 4;
10812
10813         /* last write time */
10814         CHECK_BYTE_COUNT_SUBR(4);
10815         offset = dissect_smb_datetime(tvb, tree, offset,
10816                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
10817                 FALSE);
10818         *bcp -= 4;
10819
10820         /* data size */
10821         CHECK_BYTE_COUNT_SUBR(4);
10822         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10823         COUNT_BYTES_SUBR(4);
10824
10825         /* allocation size */
10826         CHECK_BYTE_COUNT_SUBR(4);
10827         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10828         COUNT_BYTES_SUBR(4);
10829
10830         /* File Attributes */
10831         CHECK_BYTE_COUNT_SUBR(2);
10832         offset = dissect_file_attributes(tvb, tree, offset, 2);
10833         *bcp -= 2;
10834
10835         /* ea length */
10836         CHECK_BYTE_COUNT_SUBR(4);
10837         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10838         COUNT_BYTES_SUBR(4);
10839
10840         *trunc = FALSE;
10841         return offset;
10842 }
10843
10844 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
10845    as described in 4.2.16.2
10846 */
10847 static int
10848 dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10849     int offset, guint16 *bcp, gboolean *trunc)
10850 {
10851         guint8 name_len;
10852         guint16 data_len;
10853         /* EA size */
10854
10855         CHECK_BYTE_COUNT_SUBR(4);
10856         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10857         COUNT_BYTES_SUBR(4);
10858
10859         while (*bcp > 0) {
10860                 proto_item *item;
10861                 proto_tree *subtree;
10862                 int start_offset = offset;
10863                 guint8 *name;
10864
10865                 item = proto_tree_add_text(
10866                         tree, tvb, offset, 0, "Extended Attribute");
10867                 subtree = proto_item_add_subtree(item, ett_smb_ea);
10868
10869                 /* EA flags */
10870                 
10871                 CHECK_BYTE_COUNT_SUBR(1);
10872                 proto_tree_add_item(
10873                         subtree, hf_smb_ea_flags, tvb, offset, 1, TRUE);
10874                 COUNT_BYTES_SUBR(1);
10875
10876                 /* EA name length */
10877                 
10878                 name_len = tvb_get_guint8(tvb, offset);
10879
10880                 CHECK_BYTE_COUNT_SUBR(1);
10881                 proto_tree_add_item(
10882                         subtree, hf_smb_ea_name_length, tvb, offset, 1, TRUE);
10883                 COUNT_BYTES_SUBR(1);
10884
10885                 /* EA data length */
10886
10887                 data_len = tvb_get_letohs(tvb, offset);
10888                 
10889                 CHECK_BYTE_COUNT_SUBR(2);
10890                 proto_tree_add_item(
10891                         subtree, hf_smb_ea_data_length, tvb, offset, 2, TRUE);
10892                 COUNT_BYTES_SUBR(2);
10893
10894                 /* EA name */
10895
10896                 name = tvb_get_string(tvb, offset, name_len);
10897                 proto_item_append_text(item, ": %s", name);
10898                 g_free(name);
10899
10900                 CHECK_BYTE_COUNT_SUBR(name_len + 1);
10901                 proto_tree_add_item(
10902                         subtree, hf_smb_ea_name, tvb, offset, name_len + 1, 
10903                         TRUE);
10904                 COUNT_BYTES_SUBR(name_len + 1);
10905
10906                 /* EA data */
10907                 
10908                 CHECK_BYTE_COUNT_SUBR(data_len);
10909                 proto_tree_add_item(
10910                         subtree, hf_smb_ea_data, tvb, offset, data_len, TRUE);
10911                 COUNT_BYTES_SUBR(data_len);
10912
10913                 proto_item_set_len(item, offset - start_offset);
10914         }
10915
10916         *trunc = FALSE;
10917         return offset;
10918 }
10919
10920 /* this dissects the SMB_INFO_IS_NAME_VALID
10921    as described in 4.2.16.3
10922 */
10923 static int
10924 dissect_4_2_16_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10925     int offset, guint16 *bcp, gboolean *trunc)
10926 {
10927         smb_info_t *si = pinfo->private_data;
10928         int fn_len;
10929         const char *fn;
10930
10931         /* file name */
10932         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10933         CHECK_STRING_SUBR(fn);
10934         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10935                 fn);
10936         COUNT_BYTES_SUBR(fn_len);
10937
10938         *trunc = FALSE;
10939         return offset;
10940 }
10941
10942 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
10943    as described in 4.2.16.4
10944 */
10945 static int
10946 dissect_4_2_16_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10947     int offset, guint16 *bcp, gboolean *trunc)
10948 {
10949         /* create time */
10950         CHECK_BYTE_COUNT_SUBR(8);
10951         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
10952         *bcp -= 8;
10953
10954         /* access time */
10955         CHECK_BYTE_COUNT_SUBR(8);
10956         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
10957         *bcp -= 8;
10958
10959         /* last write time */
10960         CHECK_BYTE_COUNT_SUBR(8);
10961         offset = dissect_smb_64bit_time(tvb, tree, offset,
10962                 hf_smb_last_write_time);
10963         *bcp -= 8;
10964
10965         /* last change time */
10966         CHECK_BYTE_COUNT_SUBR(8);
10967         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
10968         *bcp -= 8;
10969
10970         /* File Attributes */
10971         CHECK_BYTE_COUNT_SUBR(4);
10972         offset = dissect_file_attributes(tvb, tree, offset, 4);
10973         *bcp -= 4;
10974
10975         *trunc = FALSE;
10976         return offset;
10977 }
10978
10979 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
10980    as described in 4.2.16.5
10981 */
10982 static int
10983 dissect_4_2_16_5(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10984     int offset, guint16 *bcp, gboolean *trunc)
10985 {
10986         /* allocation size */
10987         CHECK_BYTE_COUNT_SUBR(8);
10988         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10989         COUNT_BYTES_SUBR(8);
10990
10991         /* end of file */
10992         CHECK_BYTE_COUNT_SUBR(8);
10993         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10994         COUNT_BYTES_SUBR(8);
10995
10996         /* number of links */
10997         CHECK_BYTE_COUNT_SUBR(4);
10998         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
10999         COUNT_BYTES_SUBR(4);
11000
11001         /* delete pending */
11002         CHECK_BYTE_COUNT_SUBR(1);
11003         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
11004         COUNT_BYTES_SUBR(1);
11005
11006         /* is directory */
11007         CHECK_BYTE_COUNT_SUBR(1);
11008         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
11009         COUNT_BYTES_SUBR(1);
11010
11011         *trunc = FALSE;
11012         return offset;
11013 }
11014
11015 /* this dissects the SMB_QUERY_FILE_EA_INFO
11016    as described in 4.2.16.6
11017 */
11018 static int
11019 dissect_4_2_16_6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11020     int offset, guint16 *bcp, gboolean *trunc)
11021 {
11022         /* ea length */
11023         CHECK_BYTE_COUNT_SUBR(4);
11024         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11025         COUNT_BYTES_SUBR(4);
11026
11027         *trunc = FALSE;
11028         return offset;
11029 }
11030
11031 /* this dissects the SMB_QUERY_FILE_NAME_INFO
11032    as described in 4.2.16.7
11033    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
11034    as described in 4.2.16.9
11035 */
11036 static int
11037 dissect_4_2_16_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11038     int offset, guint16 *bcp, gboolean *trunc)
11039 {
11040         smb_info_t *si = pinfo->private_data;
11041         int fn_len;
11042         const char *fn;
11043
11044         /* file name len */
11045         CHECK_BYTE_COUNT_SUBR(4);
11046         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
11047         COUNT_BYTES_SUBR(4);
11048
11049         /* file name */
11050         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11051         CHECK_STRING_SUBR(fn);
11052         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11053                 fn);
11054         COUNT_BYTES_SUBR(fn_len);
11055
11056         *trunc = FALSE;
11057         return offset;
11058 }
11059
11060 /* this dissects the SMB_QUERY_FILE_ALL_INFO
11061    as described in 4.2.16.8
11062 */
11063 static int
11064 dissect_4_2_16_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11065     int offset, guint16 *bcp, gboolean *trunc)
11066 {
11067
11068         offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp, trunc);
11069         if (*trunc) {
11070                 return offset;
11071         }
11072         offset = dissect_4_2_16_5(tvb, pinfo, tree, offset, bcp, trunc);
11073         if (*trunc) {
11074                 return offset;
11075         }
11076
11077         /* index number */
11078         CHECK_BYTE_COUNT_SUBR(8);
11079         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
11080         COUNT_BYTES_SUBR(8);
11081
11082         offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp, trunc);
11083         if (*trunc)
11084                 return offset;
11085
11086         /* access flags */
11087         CHECK_BYTE_COUNT_SUBR(4);
11088         offset = dissect_smb_access_mask(tvb, tree, offset);
11089         COUNT_BYTES_SUBR(4);
11090
11091         /* index number */
11092         CHECK_BYTE_COUNT_SUBR(8);
11093         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
11094         COUNT_BYTES_SUBR(8);
11095
11096         /* current offset */
11097         CHECK_BYTE_COUNT_SUBR(8);
11098         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
11099         COUNT_BYTES_SUBR(8);
11100
11101         /* mode */
11102         CHECK_BYTE_COUNT_SUBR(4);
11103         offset = dissect_nt_create_options(tvb, tree, offset);
11104         *bcp -= 4;
11105
11106         /* alignment */
11107         CHECK_BYTE_COUNT_SUBR(4);
11108         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
11109         COUNT_BYTES_SUBR(4);
11110
11111         offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp, trunc);
11112
11113         return offset;
11114 }
11115
11116 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
11117    as described in 4.2.16.10
11118 */
11119 static int
11120 dissect_4_2_16_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11121     int offset, guint16 *bcp, gboolean *trunc)
11122 {
11123         proto_item *item;
11124         proto_tree *tree;
11125         int old_offset;
11126         guint32 neo;
11127         smb_info_t *si = pinfo->private_data;
11128         int fn_len;
11129         const char *fn;
11130         int padcnt;
11131
11132         for (;;) {
11133                 old_offset = offset;
11134
11135                 /* next entry offset */
11136                 CHECK_BYTE_COUNT_SUBR(4);
11137                 if(parent_tree){
11138                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
11139                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11140                 } else {
11141                         item = NULL;
11142                         tree = NULL;
11143                 }
11144
11145                 neo = tvb_get_letohl(tvb, offset);
11146                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11147                 COUNT_BYTES_SUBR(4);
11148
11149                 /* stream name len */
11150                 CHECK_BYTE_COUNT_SUBR(4);
11151                 fn_len = tvb_get_letohl(tvb, offset);
11152                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
11153                 COUNT_BYTES_SUBR(4);
11154
11155                 /* stream size */
11156                 CHECK_BYTE_COUNT_SUBR(8);
11157                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
11158                 COUNT_BYTES_SUBR(8);
11159
11160                 /* allocation size */
11161                 CHECK_BYTE_COUNT_SUBR(8);
11162                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11163                 COUNT_BYTES_SUBR(8);
11164
11165                 /* stream name */
11166                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11167                 CHECK_STRING_SUBR(fn);
11168                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
11169                         fn);
11170                 COUNT_BYTES_SUBR(fn_len);
11171
11172                 proto_item_append_text(item, ": %s", fn);
11173                 proto_item_set_len(item, offset-old_offset);
11174
11175                 if (neo == 0)
11176                         break;  /* no more structures */
11177
11178                 /* skip to next structure */
11179                 padcnt = (old_offset + neo) - offset;
11180                 if (padcnt < 0) {
11181                         /*
11182                          * XXX - this is bogus; flag it?
11183                          */
11184                         padcnt = 0;
11185                 }
11186                 if (padcnt != 0) {
11187                         CHECK_BYTE_COUNT_SUBR(padcnt);
11188                         COUNT_BYTES_SUBR(padcnt);
11189                 }
11190         }
11191
11192         *trunc = FALSE;
11193         return offset;
11194 }
11195
11196 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
11197    as described in 4.2.16.11
11198 */
11199 static int
11200 dissect_4_2_16_11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11201     int offset, guint16 *bcp, gboolean *trunc)
11202 {
11203         /* compressed file size */
11204         CHECK_BYTE_COUNT_SUBR(8);
11205         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
11206         COUNT_BYTES_SUBR(8);
11207
11208         /* compression format */
11209         CHECK_BYTE_COUNT_SUBR(2);
11210         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
11211         COUNT_BYTES_SUBR(2);
11212
11213         /* compression unit shift */
11214         CHECK_BYTE_COUNT_SUBR(1);
11215         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
11216         COUNT_BYTES_SUBR(1);
11217
11218         /* compression chunk shift */
11219         CHECK_BYTE_COUNT_SUBR(1);
11220         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
11221         COUNT_BYTES_SUBR(1);
11222
11223         /* compression cluster shift */
11224         CHECK_BYTE_COUNT_SUBR(1);
11225         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
11226         COUNT_BYTES_SUBR(1);
11227
11228         /* 3 reserved bytes */
11229         CHECK_BYTE_COUNT_SUBR(3);
11230         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
11231         COUNT_BYTES_SUBR(3);
11232
11233         *trunc = FALSE;
11234         return offset;
11235 }
11236
11237 /* 4.2.16.12 - SMB_QUERY_FILE_UNIX_BASIC */
11238
11239 static const value_string unix_file_type_vals[] = {
11240         { 0, "File" },
11241         { 1, "Directory" },
11242         { 2, "Symbolic link" },
11243         { 3, "Character device" },
11244         { 4, "Block device" },
11245         { 5, "FIFO" },
11246         { 6, "Socket" },
11247         { 0, NULL }
11248 };
11249
11250 static int
11251 dissect_4_2_16_12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11252                   int offset, guint16 *bcp, gboolean *trunc)
11253 {
11254         /* End of file (file size) */
11255         CHECK_BYTE_COUNT_SUBR(8);
11256         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
11257         COUNT_BYTES_SUBR(8);
11258
11259         /* Number of bytes */
11260         CHECK_BYTE_COUNT_SUBR(8);
11261         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
11262         COUNT_BYTES_SUBR(8);
11263
11264         /* Last status change */
11265         CHECK_BYTE_COUNT_SUBR(8);
11266         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
11267         *bcp -= 8;              /* dissect_smb_64bit_time() increments offset */
11268
11269         /* Last access time */
11270         CHECK_BYTE_COUNT_SUBR(8);
11271         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
11272         *bcp -= 8;
11273
11274         /* Last modification time */
11275         CHECK_BYTE_COUNT_SUBR(8);
11276         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
11277         *bcp -= 8;
11278
11279         /* File owner uid */
11280         CHECK_BYTE_COUNT_SUBR(8);
11281         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
11282         COUNT_BYTES_SUBR(8);
11283
11284         /* File group gid */
11285         CHECK_BYTE_COUNT_SUBR(8);
11286         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
11287         COUNT_BYTES_SUBR(8);
11288
11289         /* File type */
11290         CHECK_BYTE_COUNT_SUBR(4);
11291         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
11292         COUNT_BYTES_SUBR(4);
11293
11294         /* Major device number */
11295         CHECK_BYTE_COUNT_SUBR(8);
11296         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
11297         COUNT_BYTES_SUBR(8);
11298
11299         /* Minor device number */
11300         CHECK_BYTE_COUNT_SUBR(8);
11301         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
11302         COUNT_BYTES_SUBR(8);
11303
11304         /* Unique id */
11305         CHECK_BYTE_COUNT_SUBR(8);
11306         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
11307         COUNT_BYTES_SUBR(8);
11308
11309         /* Permissions */
11310         CHECK_BYTE_COUNT_SUBR(8);
11311         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
11312         COUNT_BYTES_SUBR(8);
11313
11314         /* Nlinks */
11315         CHECK_BYTE_COUNT_SUBR(8);
11316         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
11317         COUNT_BYTES_SUBR(8);
11318
11319         /* Sometimes there is one extra byte in the data field which I
11320            guess could be padding, but we are only using 4 or 8 byte
11321            data types so this is a bit confusing. -tpot */
11322
11323         *trunc = FALSE;
11324         return offset;
11325 }
11326
11327 /* 4.2.16.13 - SMB_QUERY_FILE_UNIX_LINK */
11328
11329 static int
11330 dissect_4_2_16_13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11331                   int offset, guint16 *bcp, gboolean *trunc)
11332 {
11333         smb_info_t *si = pinfo->private_data;
11334         const char *fn;
11335         int fn_len;
11336
11337         /* Link destination */
11338
11339         fn = get_unicode_or_ascii_string(
11340                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11341
11342         CHECK_STRING_SUBR(fn);
11343         proto_tree_add_string(
11344                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
11345         COUNT_BYTES_SUBR(fn_len);
11346
11347         *trunc = FALSE;
11348         return offset;
11349 }
11350
11351 /* this dissects the SMB_SET_FILE_DISPOSITION_INFO
11352    as described in 4.2.19.2
11353 */
11354 static int
11355 dissect_4_2_19_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11356     int offset, guint16 *bcp, gboolean *trunc)
11357 {
11358         /* marked for deletion? */
11359         CHECK_BYTE_COUNT_SUBR(1);
11360         proto_tree_add_item(tree, hf_smb_t2_marked_for_deletion, tvb, offset, 1, TRUE);
11361         COUNT_BYTES_SUBR(1);
11362
11363         *trunc = FALSE;
11364         return offset;
11365 }
11366
11367 /* this dissects the SMB_SET_FILE_ALLOCATION_INFO
11368    as described in 4.2.19.3
11369 */
11370 static int
11371 dissect_4_2_19_3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11372     int offset, guint16 *bcp, gboolean *trunc)
11373 {
11374         /* file allocation size */
11375         CHECK_BYTE_COUNT_SUBR(8);
11376         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11377         COUNT_BYTES_SUBR(8);
11378
11379         *trunc = FALSE;
11380         return offset;
11381 }
11382
11383 /* this dissects the SMB_SET_FILE_END_OF_FILE_INFO
11384    as described in 4.2.19.4
11385 */
11386 static int
11387 dissect_4_2_19_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11388     int offset, guint16 *bcp, gboolean *trunc)
11389 {
11390         /* file end of file offset */
11391         CHECK_BYTE_COUNT_SUBR(8);
11392         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11393         COUNT_BYTES_SUBR(8);
11394
11395         *trunc = FALSE;
11396         return offset;
11397 }
11398
11399 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION and
11400   TRANS2_QUERY_FILE_INFORMATION*/
11401 static int
11402 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11403     int offset, guint16 *bcp)
11404 {
11405         smb_info_t *si;
11406         gboolean trunc;
11407
11408         if(!*bcp){
11409                 return offset;
11410         }
11411
11412         si = (smb_info_t *)pinfo->private_data;
11413         switch(si->info_level){
11414         case 1:         /*Info Standard*/
11415                 
11416         case 2:         /*Info Query EA Size*/
11417                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
11418                     &trunc);
11419                 break;
11420         case 3:         /*Info Query EAs From List*/
11421         case 4:         /*Info Query All EAs*/
11422                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11423                     &trunc);
11424                 break;
11425         case 6:         /*Info Is Name Valid*/
11426                 offset = dissect_4_2_16_3(tvb, pinfo, tree, offset, bcp,
11427                     &trunc);
11428                 break;
11429         case 0x0101:    /*Query File Basic Info*/
11430         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
11431                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11432                     &trunc);
11433                 break;
11434         case 0x0102:    /*Query File Standard Info*/
11435         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
11436                 offset = dissect_4_2_16_5(tvb, pinfo, tree, offset, bcp,
11437                     &trunc);
11438                 break;
11439         case 0x0103:    /*Query File EA Info*/
11440         case 1007:      /* SMB_FILE_EA_INFORMATION */
11441                 offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp,
11442                     &trunc);
11443                 break;
11444         case 0x0104:    /*Query File Name Info*/
11445         case 1009:      /* SMB_FILE_NAME_INFORMATION */
11446                 offset = dissect_4_2_16_7(tvb, pinfo, tree, offset, bcp,
11447                     &trunc);
11448                 break;
11449         case 0x0107:    /*Query File All Info*/
11450         case 1018:      /* SMB_FILE_ALL_INFORMATION */
11451                 offset = dissect_4_2_16_8(tvb, pinfo, tree, offset, bcp,
11452                     &trunc);
11453                 break;
11454         case 0x0108:    /*Query File Alt File Info*/
11455         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
11456                 offset = dissect_4_2_16_7(tvb, pinfo, tree, offset, bcp,
11457                     &trunc);
11458                 break;
11459         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
11460                 ((smb_info_t *)(pinfo->private_data))->unicode = TRUE;
11461         case 0x0109:    /*Query File Stream Info*/
11462                 offset = dissect_4_2_16_10(tvb, pinfo, tree, offset, bcp,
11463                     &trunc);
11464                 break;
11465         case 0x010b:    /*Query File Compression Info*/
11466         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
11467                 offset = dissect_4_2_16_11(tvb, pinfo, tree, offset, bcp,
11468                     &trunc);
11469                 break;
11470         case 0x0200:    /* Query File Unix Basic*/
11471                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp, 
11472                                            &trunc);
11473                 break;
11474         case 0x0201:    /* Query File Unix Link*/
11475                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp, 
11476                                            &trunc);
11477                 break;
11478         case 0x0202:    /* Query File Unix HardLink*/
11479                 /* XXX add this from the SNIA doc */
11480                 break;
11481         }
11482
11483         return offset;
11484 }
11485
11486 /*dissect the data block for TRANS2_SET_PATH_INFORMATION and
11487   TRANS2_SET_FILE_INFORMATION*/
11488 static int
11489 dissect_spi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11490     int offset, guint16 *bcp)
11491 {
11492         smb_info_t *si;
11493         gboolean trunc;
11494
11495         if(!*bcp){
11496                 return offset;
11497         }
11498
11499         si = (smb_info_t *)pinfo->private_data;
11500         switch(si->info_level){
11501         case 1:         /*Info Standard*/
11502                 
11503         case 2:         /*Info Query EA Size*/
11504                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
11505                     &trunc);
11506                 break;
11507         case 4:         /*Info Query All EAs*/
11508                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11509                     &trunc);
11510                 break;
11511         case 0x0101:    /*Set File Basic Info*/
11512                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11513                     &trunc);
11514                 break;
11515         case 0x0102:    /*Set File Disposition Info*/
11516                 offset = dissect_4_2_19_2(tvb, pinfo, tree, offset, bcp,
11517                     &trunc);
11518                 break;
11519         case 0x0103:    /*Set File Allocation Info*/
11520                 offset = dissect_4_2_19_3(tvb, pinfo, tree, offset, bcp,
11521                     &trunc);
11522                 break;
11523         case 0x0104:    /*Set End Of File Info*/
11524                 offset = dissect_4_2_19_4(tvb, pinfo, tree, offset, bcp,
11525                     &trunc);
11526                 break;
11527         case 0x0200:    /*Set File Unix Basic.  Same as query. */
11528                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
11529                     &trunc);
11530                 break;
11531         case 0x0201:    /*Set File Unix Link.  Same as query. */
11532                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
11533                     &trunc);
11534                 break;
11535         case 0x0203:    /*Set File Unix HardLink.  Same as link query. */
11536                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
11537                     &trunc);
11538                 break;
11539         case 1004:
11540                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11541                     &trunc);
11542                 break;
11543         case 1010:
11544         case 1013:
11545         case 1014:
11546         case 1016:
11547         case 1019:
11548         case 1020:
11549         case 1023:
11550         case 1025:
11551         case 1029:
11552         case 1032:
11553         case 1039:
11554         case 1040:
11555                 /* XXX: TODO, extra levels discovered by tridge */
11556                 break;
11557         }
11558
11559         return offset;
11560 }
11561
11562
11563 static const true_false_string tfs_quota_flags_deny_disk = {
11564         "DENY DISK SPACE for users exceeding quota limit",
11565         "Do NOT deny disk space for users exceeding quota limit"
11566 };
11567 static const true_false_string tfs_quota_flags_log_limit = {
11568         "LOG EVENT when a user exceeds their QUOTA LIMIT",
11569         "Do NOT log event when a user exceeds their quota limit"
11570 };
11571 static const true_false_string tfs_quota_flags_log_warning = {
11572         "LOG EVENT when a user exceeds their WARNING LEVEL",
11573         "Do NOT log event when a user exceeds their warning level"
11574 };
11575 static const true_false_string tfs_quota_flags_enabled = {
11576         "Quotas are ENABLED of this fs",
11577         "Quotas are NOT enabled on this fs"
11578 };
11579 static void
11580 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11581 {
11582         guint8 mask;
11583         proto_item *item = NULL;
11584         proto_tree *tree = NULL;
11585
11586         mask = tvb_get_guint8(tvb, offset);
11587
11588         if(parent_tree){
11589                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
11590                         "Quota Flags: 0x%02x %s", mask,
11591                         mask?"Enabled":"Disabled");
11592                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
11593         }
11594
11595         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
11596                 tvb, offset, 1, mask);
11597         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
11598                 tvb, offset, 1, mask);
11599         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
11600                 tvb, offset, 1, mask);
11601
11602         if(mask && (!(mask&0x01))){
11603                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
11604                         tvb, offset, 1, 0x01);
11605         } else {
11606                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
11607                         tvb, offset, 1, mask);
11608         }
11609
11610 }
11611
11612 static int
11613 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
11614 {
11615         /* first 24 bytes are unknown */
11616         CHECK_BYTE_COUNT_TRANS_SUBR(24);
11617         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11618                     offset, 24, TRUE);
11619         COUNT_BYTES_TRANS_SUBR(24);
11620
11621         /* number of bytes for quota warning */
11622         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11623         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
11624         COUNT_BYTES_TRANS_SUBR(8);
11625
11626         /* number of bytes for quota limit */
11627         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11628         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
11629         COUNT_BYTES_TRANS_SUBR(8);
11630
11631         /* one byte of quota flags */
11632         CHECK_BYTE_COUNT_TRANS_SUBR(1);
11633         dissect_quota_flags(tvb, tree, offset);
11634         COUNT_BYTES_TRANS_SUBR(1);
11635
11636         /* these 7 bytes are unknown */
11637         CHECK_BYTE_COUNT_TRANS_SUBR(7);
11638         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11639                     offset, 7, TRUE);
11640         COUNT_BYTES_TRANS_SUBR(7);
11641
11642         return offset;
11643 }
11644
11645 static int
11646 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
11647     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
11648 {
11649         proto_item *item = NULL;
11650         proto_tree *tree = NULL;
11651         smb_info_t *si;
11652
11653         si = (smb_info_t *)pinfo->private_data;
11654
11655         if(parent_tree){
11656                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
11657                                 "%s Data",
11658                                 val_to_str(subcmd, trans2_cmd_vals,
11659                                                 "Unknown (0x%02x)"));
11660                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
11661         }
11662
11663         switch(subcmd){
11664         case 0x00:      /*TRANS2_OPEN2*/
11665                 /* XXX dont know how to decode FEAList */
11666                 break;
11667         case 0x01:      /*TRANS2_FIND_FIRST2*/
11668                 /* XXX dont know how to decode FEAList */
11669                 break;
11670         case 0x02:      /*TRANS2_FIND_NEXT2*/
11671                 /* XXX dont know how to decode FEAList */
11672                 break;
11673         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
11674                 /* no data field in this request */
11675                 break;
11676         case 0x04:      /* TRANS2_SET_QUOTA */
11677                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
11678                 break;
11679         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
11680                 /* no data field in this request */
11681                 /*
11682                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11683                  * Extensions Version 3.0, Document Version 1.11,
11684                  * July 19, 1990" says there may be "Additional
11685                  * FileInfoLevel dependent information" here.
11686                  *
11687                  * Was that just a cut-and-pasteo?
11688                  * TRANS2_SET_PATH_INFORMATION *does* have that information
11689                  * here.
11690                  */
11691                 break;
11692         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
11693                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
11694                 break;
11695         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
11696                 /* no data field in this request */
11697                 /*
11698                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11699                  * Extensions Version 3.0, Document Version 1.11,
11700                  * July 19, 1990" says there may be "Additional
11701                  * FileInfoLevel dependent information" here.
11702                  *
11703                  * Was that just a cut-and-pasteo?
11704                  * TRANS2_SET_FILE_INFORMATION *does* have that information
11705                  * here.
11706                  */
11707                 break;
11708         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
11709                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
11710                 break;
11711         case 0x09:      /*TRANS2_FSCTL*/
11712                 /*XXX dont know how to decode this yet */
11713
11714                 /*
11715                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11716                  * Extensions Version 3.0, Document Version 1.11,
11717                  * July 19, 1990" says this this contains a
11718                  * "File system specific data block".  (That means we
11719                  * may not be able to dissect it in any case.)
11720                  */
11721                 break;
11722         case 0x0a:      /*TRANS2_IOCTL2*/
11723                 /*XXX dont know how to decode this yet */
11724
11725                 /*
11726                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11727                  * Extensions Version 3.0, Document Version 1.11,
11728                  * July 19, 1990" says this this contains a
11729                  * "Device/function specific data block".  (That
11730                  * means we may not be able to dissect it in any case.)
11731                  */
11732                 break;
11733         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11734                 /*XXX dont know how to decode this yet */
11735
11736                 /*
11737                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11738                  * Extensions Version 3.0, Document Version 1.11,
11739                  * July 19, 1990" says this this contains "additional
11740                  * level dependent match data".
11741                  */
11742                 break;
11743         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11744                 /*XXX dont know how to decode this yet */
11745
11746                 /*
11747                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11748                  * Extensions Version 3.0, Document Version 1.11,
11749                  * July 19, 1990" says this this contains "additional
11750                  * level dependent monitor information".
11751                  */
11752                 break;
11753         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11754                 /* XXX optional FEAList, unknown what FEAList looks like*/
11755                 break;
11756         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11757                 /*XXX dont know how to decode this yet */
11758                 break;
11759         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11760                 /* no data field in this request */
11761                 break;
11762         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11763                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
11764                 break;
11765         }
11766
11767         /* ooops there were data we didnt know how to process */
11768         if(dc != 0){
11769                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
11770                 offset += dc;
11771         }
11772
11773         return offset;
11774 }
11775
11776
11777 static void
11778 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
11779     proto_tree *tree)
11780 {
11781         int i;
11782         int offset;
11783         guint length;
11784
11785         /*
11786          * Show the setup words.
11787          */
11788         if (s_tvb != NULL) {
11789                 length = tvb_reported_length(s_tvb);
11790                 for (i = 0, offset = 0; length >= 2;
11791                     i++, offset += 2, length -= 2) {
11792                         /*
11793                          * XXX - add a setup word filterable field?
11794                          */
11795                         proto_tree_add_text(tree, s_tvb, offset, 2,
11796                             "Setup Word %d: 0x%04x", i,
11797                             tvb_get_letohs(s_tvb, offset));
11798                 }
11799         }
11800
11801         /*
11802          * Show the parameters, if any.
11803          */
11804         if (p_tvb != NULL) {
11805                 length = tvb_reported_length(p_tvb);
11806                 if (length != 0) {
11807                         proto_tree_add_text(tree, p_tvb, 0, length,
11808                             "Parameters: %s",
11809                             tvb_bytes_to_str(p_tvb, 0, length));
11810                 }
11811         }
11812
11813         /*
11814          * Show the data, if any.
11815          */
11816         if (d_tvb != NULL) {
11817                 length = tvb_reported_length(d_tvb);
11818                 if (length != 0) {
11819                         proto_tree_add_text(tree, d_tvb, 0, length,
11820                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
11821                 }
11822         }
11823 }
11824
11825 /* This routine handles the following 4 calls
11826    Transaction  0x25
11827    Transaction Secondary 0x26
11828    Transaction2 0x32
11829    Transaction2 Secondary 0x33
11830 */
11831 static int
11832 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
11833 {
11834         guint8 wc, sc=0;
11835         int so=offset;
11836         int sl=0;
11837         int spo=offset;
11838         int spc=0;
11839         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
11840         int subcmd = -1;
11841         guint32 to;
11842         int an_len;
11843         const char *an = NULL;
11844         smb_info_t *si;
11845         smb_transact2_info_t *t2i;
11846         smb_transact_info_t *tri;
11847         guint16 bc;
11848         int padcnt;
11849         gboolean dissected_trans;
11850
11851         si = (smb_info_t *)pinfo->private_data;
11852
11853         WORD_COUNT;
11854
11855         if(wc==8){
11856                 /*secondary client request*/
11857
11858                 /* total param count, only a 16bit integer here*/
11859                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11860                 offset += 2;
11861
11862                 /* total data count , only 16bit integer here*/
11863                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11864                 offset += 2;
11865
11866                 /* param count */
11867                 pc = tvb_get_letohs(tvb, offset);
11868                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11869                 offset += 2;
11870
11871                 /* param offset */
11872                 po = tvb_get_letohs(tvb, offset);
11873                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11874                 offset += 2;
11875
11876                 /* param disp */
11877                 pd = tvb_get_letohs(tvb, offset);
11878                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
11879                 offset += 2;
11880
11881                 /* data count */
11882                 dc = tvb_get_letohs(tvb, offset);
11883                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11884                 offset += 2;
11885
11886                 /* data offset */
11887                 od = tvb_get_letohs(tvb, offset);
11888                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11889                 offset += 2;
11890
11891                 /* data disp */
11892                 dd = tvb_get_letohs(tvb, offset);
11893                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
11894                 offset += 2;
11895
11896                 if(si->cmd==SMB_COM_TRANSACTION2){
11897                         guint16 fid;
11898
11899                         /* fid */
11900                         fid = tvb_get_letohs(tvb, offset);
11901                         add_fid(tvb, pinfo, tree, offset, 2, fid);
11902
11903                         offset += 2;
11904                 }
11905
11906                 /* There are no setup words. */
11907                 so = offset;
11908                 sc = 0;
11909                 sl = 0;
11910         } else {
11911                 /* it is not a secondary request */
11912
11913                 /* total param count , only a 16 bit integer here*/
11914                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11915                 offset += 2;
11916
11917                 /* total data count , only 16bit integer here*/
11918                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11919                 offset += 2;
11920
11921                 /* max param count , only 16bit integer here*/
11922                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11923                 offset += 2;
11924
11925                 /* max data count, only 16bit integer here*/
11926                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11927                 offset += 2;
11928
11929                 /* max setup count, only 16bit integer here*/
11930                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
11931                 offset += 1;
11932
11933                 /* reserved byte */
11934                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11935                 offset += 1;
11936
11937                 /* transaction flags */
11938                 tf = dissect_transaction_flags(tvb, tree, offset);
11939                 offset += 2;
11940
11941                 /* timeout */
11942                 to = tvb_get_letohl(tvb, offset);
11943                 if (to == 0)
11944                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
11945                 else if (to == 0xffffffff)
11946                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
11947                 else
11948                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
11949                 offset += 4;
11950
11951                 /* 2 reserved bytes */
11952                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
11953                 offset += 2;
11954
11955                 /* param count */
11956                 pc = tvb_get_letohs(tvb, offset);
11957                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11958                 offset += 2;
11959
11960                 /* param offset */
11961                 po = tvb_get_letohs(tvb, offset);
11962                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11963                 offset += 2;
11964
11965                 /* param displacement is zero here */
11966                 pd = 0;
11967
11968                 /* data count */
11969                 dc = tvb_get_letohs(tvb, offset);
11970                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11971                 offset += 2;
11972
11973                 /* data offset */
11974                 od = tvb_get_letohs(tvb, offset);
11975                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11976                 offset += 2;
11977
11978                 /* data displacement is zero here */
11979                 dd = 0;
11980
11981                 /* setup count */
11982                 sc = tvb_get_guint8(tvb, offset);
11983                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
11984                 offset += 1;
11985
11986                 /* reserved byte */
11987                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11988                 offset += 1;
11989
11990                 /* this is where the setup bytes, if any start */
11991                 so = offset;
11992                 sl = sc*2;
11993
11994                 /* if there were any setup bytes, decode them */
11995                 if(sc){
11996                         switch(si->cmd){
11997
11998                         case SMB_COM_TRANSACTION2:
11999                                 /* TRANSACTION2 only has one setup word and
12000                                    that is the subcommand code.
12001
12002                                    XXX - except for TRANS2_FSCTL
12003                                    and TRANS2_IOCTL. */
12004                                 subcmd = tvb_get_letohs(tvb, offset);
12005                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
12006                                     tvb, offset, 2, subcmd);
12007                                 if (check_col(pinfo->cinfo, COL_INFO)) {
12008                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
12009                                             val_to_str(subcmd, trans2_cmd_vals,
12010                                                 "Unknown (0x%02x)"));
12011                                 }
12012                                 if (!si->unidir) {
12013                                         if(!pinfo->fd->flags.visited){
12014                                                 /*
12015                                                  * Allocate a new
12016                                                  * smb_transact2_info_t
12017                                                  * structure.
12018                                                  */
12019                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
12020                                                 t2i->subcmd = subcmd;
12021                                                 t2i->info_level = -1;
12022                                                 t2i->resume_keys = FALSE;
12023                                                 si->sip->extra_info = t2i;
12024                                         }
12025                                 }
12026
12027                                 /*
12028                                  * XXX - process TRANS2_FSCTL and
12029                                  * TRANS2_IOCTL setup words here.
12030                                  */
12031                                 break;
12032
12033                         case SMB_COM_TRANSACTION:
12034                                 /* TRANSACTION setup words processed below */
12035                                 break;
12036                         }
12037
12038                         offset += sl;
12039                 }
12040         }
12041
12042         BYTE_COUNT;
12043
12044         if(wc!=8){
12045                 /* primary request */
12046                 /* name is NULL if transaction2 */
12047                 if(si->cmd == SMB_COM_TRANSACTION){
12048                         /* Transaction Name */
12049                         an = get_unicode_or_ascii_string(tvb, &offset,
12050                                 si->unicode, &an_len, FALSE, FALSE, &bc);
12051                         if (an == NULL)
12052                                 goto endofcommand;
12053                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
12054                                 offset, an_len, an);
12055                         COUNT_BYTES(an_len);
12056                 }
12057         }
12058
12059         /*
12060          * The pipe or mailslot arguments for Transaction start with
12061          * the first setup word (or where the first setup word would
12062          * be if there were any setup words), and run to the current
12063          * offset (which could mean that there aren't any).
12064          */
12065         spo = so;
12066         spc = offset - spo;
12067
12068         /* parameters */
12069         if(po>offset){
12070                 /* We have some initial padding bytes.
12071                 */
12072                 padcnt = po-offset;
12073                 if (padcnt > bc)
12074                         padcnt = bc;
12075                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12076                 COUNT_BYTES(padcnt);
12077         }
12078         if(pc){
12079                 CHECK_BYTE_COUNT(pc);
12080                 switch(si->cmd) {
12081
12082                 case SMB_COM_TRANSACTION2:
12083                         /* TRANSACTION2 parameters*/
12084                         offset = dissect_transaction2_request_parameters(tvb,
12085                             pinfo, tree, offset, subcmd, pc);
12086                         bc -= pc;
12087                         break;
12088
12089                 case SMB_COM_TRANSACTION:
12090                         /* TRANSACTION parameters processed below */
12091                         COUNT_BYTES(pc);
12092                         break;
12093                 }
12094         }
12095
12096         /* data */
12097         if(od>offset){
12098                 /* We have some initial padding bytes.
12099                 */
12100                 padcnt = od-offset;
12101                 if (padcnt > bc)
12102                         padcnt = bc;
12103                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12104                 COUNT_BYTES(padcnt);
12105         }
12106         if(dc){
12107                 CHECK_BYTE_COUNT(dc);
12108                 switch(si->cmd){
12109
12110                 case SMB_COM_TRANSACTION2:
12111                         /* TRANSACTION2 data*/
12112                         offset = dissect_transaction2_request_data(tvb, pinfo,
12113                             tree, offset, subcmd, dc);
12114                         bc -= dc;
12115                         break;
12116
12117                 case SMB_COM_TRANSACTION:
12118                         /* TRANSACTION data processed below */
12119                         COUNT_BYTES(dc);
12120                         break;
12121                 }
12122         }
12123
12124         /*TRANSACTION request parameters */
12125         if(si->cmd==SMB_COM_TRANSACTION){
12126                 /*XXX replace this block with a function and use that one
12127                      for both requests/responses*/
12128                 if(dd==0){
12129                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
12130                         tvbuff_t *sp_tvb, *pd_tvb;
12131
12132                         if(pc>0){
12133                                 if(pc>tvb_length_remaining(tvb, po)){
12134                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
12135                                 } else {
12136                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
12137                                 }
12138                         } else {
12139                                 p_tvb = NULL;
12140                         }
12141                         if(dc>0){
12142                                 if(dc>tvb_length_remaining(tvb, od)){
12143                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
12144                                 } else {
12145                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
12146                                 }
12147                         } else {
12148                                 d_tvb = NULL;
12149                         }
12150                         if(sl){
12151                                 if(sl>tvb_length_remaining(tvb, so)){
12152                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
12153                                 } else {
12154                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
12155                                 }
12156                         } else {
12157                                 s_tvb = NULL;
12158                         }
12159
12160                         if (!si->unidir) {
12161                                 if(!pinfo->fd->flags.visited){
12162                                         /*
12163                                          * Allocate a new smb_transact_info_t
12164                                          * structure.
12165                                          */
12166                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
12167                                         tri->subcmd = -1;
12168                                         tri->trans_subcmd = -1;
12169                                         tri->function = -1;
12170                                         tri->fid = -1;
12171                                         tri->lanman_cmd = 0;
12172                                         tri->param_descrip = NULL;
12173                                         tri->data_descrip = NULL;
12174                                         tri->aux_data_descrip = NULL;
12175                                         tri->info_level = -1;
12176                                         si->sip->extra_info = tri;
12177                                 } else {
12178                                         /*
12179                                          * We already filled the structure
12180                                          * in; don't bother doing so again.
12181                                          */
12182                                         tri = NULL;
12183                                 }
12184                         } else {
12185                                 /*
12186                                  * This is a unidirectional message, for
12187                                  * which there will be no reply; don't
12188                                  * bother allocating an "smb_transact_info_t"
12189                                  * structure for it.
12190                                  */
12191                                 tri = NULL;
12192                         }
12193                         dissected_trans = FALSE;
12194                         if(strncmp("\\PIPE\\", an, 6) == 0){
12195                                 if (tri != NULL)
12196                                         tri->subcmd=TRANSACTION_PIPE;
12197
12198                                 /*
12199                                  * A tvbuff containing the setup words and
12200                                  * the pipe path.
12201                                  */
12202                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
12203
12204                                 /*
12205                                  * A tvbuff containing the parameters and the
12206                                  * data.
12207                                  */
12208                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
12209
12210                                 dissected_trans = dissect_pipe_smb(sp_tvb,
12211                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
12212                                     top_tree);
12213
12214                                 /* In case we did not see the TreeConnect call,
12215                                    store this TID here as well as a IPC TID 
12216                                    so we know that future Read/Writes to this 
12217                                    TID is (probably) DCERPC.
12218                                 */
12219                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
12220                                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
12221                                 }
12222                                 g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
12223                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
12224                                 if (tri != NULL)
12225                                         tri->subcmd=TRANSACTION_MAILSLOT;
12226
12227                                 /*
12228                                  * A tvbuff containing the setup words and
12229                                  * the mailslot path.
12230                                  */
12231                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
12232                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
12233                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
12234                         }
12235                         if (!dissected_trans)
12236                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
12237                 } else {
12238                         if(check_col(pinfo->cinfo, COL_INFO)){
12239                                 col_append_str(pinfo->cinfo, COL_INFO,
12240                                         "[transact continuation]");
12241                         }
12242                 }
12243         }
12244
12245         END_OF_SMB
12246
12247         return offset;
12248 }
12249
12250
12251
12252 static int
12253 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12254     int offset, guint16 *bcp, gboolean *trunc)
12255 {
12256         int fn_len;
12257         const char *fn;
12258         int old_offset = offset;
12259         proto_item *item = NULL;
12260         proto_tree *tree = NULL;
12261         smb_info_t *si;
12262         smb_transact2_info_t *t2i;
12263         gboolean resume_keys = FALSE;
12264
12265         si = (smb_info_t *)pinfo->private_data;
12266         if (si->sip != NULL) {
12267                 t2i = si->sip->extra_info;
12268                 if (t2i != NULL)
12269                         resume_keys = t2i->resume_keys;
12270         }
12271
12272         if(parent_tree){
12273                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12274                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12275                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12276         }
12277
12278         if (resume_keys) {
12279                 /* resume key */
12280                 CHECK_BYTE_COUNT_SUBR(4);
12281                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
12282                 COUNT_BYTES_SUBR(4);
12283         }
12284
12285         /* create time */
12286         CHECK_BYTE_COUNT_SUBR(4);
12287         offset = dissect_smb_datetime(tvb, tree, offset,
12288                 hf_smb_create_time,
12289                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
12290         *bcp -= 4;
12291
12292         /* access time */
12293         CHECK_BYTE_COUNT_SUBR(4);
12294         offset = dissect_smb_datetime(tvb, tree, offset,
12295                 hf_smb_access_time,
12296                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
12297         *bcp -= 4;
12298
12299         /* last write time */
12300         CHECK_BYTE_COUNT_SUBR(4);
12301         offset = dissect_smb_datetime(tvb, tree, offset,
12302                 hf_smb_last_write_time,
12303                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
12304         *bcp -= 4;
12305
12306         /* data size */
12307         CHECK_BYTE_COUNT_SUBR(4);
12308         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12309         COUNT_BYTES_SUBR(4);
12310
12311         /* allocation size */
12312         CHECK_BYTE_COUNT_SUBR(4);
12313         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
12314         COUNT_BYTES_SUBR(4);
12315
12316         /* File Attributes */
12317         CHECK_BYTE_COUNT_SUBR(2);
12318         offset = dissect_file_attributes(tvb, tree, offset, 2);
12319         *bcp -= 2;
12320
12321         /* file name len */
12322         CHECK_BYTE_COUNT_SUBR(1);
12323         fn_len = tvb_get_guint8(tvb, offset);
12324         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
12325         COUNT_BYTES_SUBR(1);
12326         if (si->unicode)
12327                 fn_len += 2;    /* include terminating '\0' */
12328         else
12329                 fn_len++;       /* include terminating '\0' */
12330
12331         /* file name */
12332         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12333         CHECK_STRING_SUBR(fn);
12334         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12335                 fn);
12336         COUNT_BYTES_SUBR(fn_len);
12337
12338         if (check_col(pinfo->cinfo, COL_INFO)) {
12339                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12340                 fn);
12341         }
12342
12343         proto_item_append_text(item, " File: %s", fn);
12344         proto_item_set_len(item, offset-old_offset);
12345
12346         *trunc = FALSE;
12347         return offset;
12348 }
12349
12350 static int
12351 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12352     int offset, guint16 *bcp, gboolean *trunc)
12353 {
12354         int fn_len;
12355         const char *fn;
12356         int old_offset = offset;
12357         proto_item *item = NULL;
12358         proto_tree *tree = NULL;
12359         smb_info_t *si;
12360         smb_transact2_info_t *t2i;
12361         gboolean resume_keys = FALSE;
12362
12363         si = (smb_info_t *)pinfo->private_data;
12364         if (si->sip != NULL) {
12365                 t2i = si->sip->extra_info;
12366                 if (t2i != NULL)
12367                         resume_keys = t2i->resume_keys;
12368         }
12369
12370         if(parent_tree){
12371                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12372                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12373                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12374         }
12375
12376         if (resume_keys) {
12377                 /* resume key */
12378                 CHECK_BYTE_COUNT_SUBR(4);
12379                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
12380                 COUNT_BYTES_SUBR(4);
12381         }
12382
12383         /* create time */
12384         CHECK_BYTE_COUNT_SUBR(4);
12385         offset = dissect_smb_datetime(tvb, tree, offset,
12386                 hf_smb_create_time,
12387                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
12388         *bcp -= 4;
12389
12390         /* access time */
12391         CHECK_BYTE_COUNT_SUBR(4);
12392         offset = dissect_smb_datetime(tvb, tree, offset,
12393                 hf_smb_access_time,
12394                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
12395         *bcp -= 4;
12396
12397         /* last write time */
12398         CHECK_BYTE_COUNT_SUBR(4);
12399         offset = dissect_smb_datetime(tvb, tree, offset,
12400                 hf_smb_last_write_time,
12401                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
12402         *bcp -= 4;
12403
12404         /* data size */
12405         CHECK_BYTE_COUNT_SUBR(4);
12406         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12407         COUNT_BYTES_SUBR(4);
12408
12409         /* allocation size */
12410         CHECK_BYTE_COUNT_SUBR(4);
12411         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
12412         COUNT_BYTES_SUBR(4);
12413
12414         /* File Attributes */
12415         CHECK_BYTE_COUNT_SUBR(2);
12416         offset = dissect_file_attributes(tvb, tree, offset, 2);
12417         *bcp -= 2;
12418
12419         /* ea length */
12420         CHECK_BYTE_COUNT_SUBR(4);
12421         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12422         COUNT_BYTES_SUBR(4);
12423
12424         /* file name len */
12425         CHECK_BYTE_COUNT_SUBR(1);
12426         fn_len = tvb_get_guint8(tvb, offset);
12427         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
12428         COUNT_BYTES_SUBR(1);
12429         if (si->unicode)
12430                 fn_len += 2;    /* include terminating '\0' */
12431         else
12432                 fn_len++;       /* include terminating '\0' */
12433
12434         /* file name */
12435         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12436         CHECK_STRING_SUBR(fn);
12437         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12438                 fn);
12439         COUNT_BYTES_SUBR(fn_len);
12440
12441         if (check_col(pinfo->cinfo, COL_INFO)) {
12442                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12443                 fn);
12444         }
12445
12446         proto_item_append_text(item, " File: %s", fn);
12447         proto_item_set_len(item, offset-old_offset);
12448
12449         *trunc = FALSE;
12450         return offset;
12451 }
12452
12453 static int
12454 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12455     int offset, guint16 *bcp, gboolean *trunc)
12456 {
12457         int fn_len;
12458         const char *fn;
12459         int old_offset = offset;
12460         proto_item *item = NULL;
12461         proto_tree *tree = NULL;
12462         smb_info_t *si;
12463         guint32 neo;
12464         int padcnt;
12465
12466         si = (smb_info_t *)pinfo->private_data;
12467
12468         if(parent_tree){
12469                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12470                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12471                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12472         }
12473
12474         /*
12475          * We assume that the presence of a next entry offset implies the
12476          * absence of a resume key, as appears to be the case for 4.3.4.6.
12477          */
12478
12479         /* next entry offset */
12480         CHECK_BYTE_COUNT_SUBR(4);
12481         neo = tvb_get_letohl(tvb, offset);
12482         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12483         COUNT_BYTES_SUBR(4);
12484
12485         /* file index */
12486         CHECK_BYTE_COUNT_SUBR(4);
12487         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12488         COUNT_BYTES_SUBR(4);
12489
12490         /* create time */
12491         CHECK_BYTE_COUNT_SUBR(8);
12492         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12493         *bcp -= 8;
12494
12495         /* access time */
12496         CHECK_BYTE_COUNT_SUBR(8);
12497         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12498         *bcp -= 8;
12499
12500         /* last write time */
12501         CHECK_BYTE_COUNT_SUBR(8);
12502         offset = dissect_smb_64bit_time(tvb, tree, offset,
12503                 hf_smb_last_write_time);
12504         *bcp -= 8;
12505
12506         /* last change time */
12507         CHECK_BYTE_COUNT_SUBR(8);
12508         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12509         *bcp -= 8;
12510
12511         /* end of file */
12512         CHECK_BYTE_COUNT_SUBR(8);
12513         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12514         COUNT_BYTES_SUBR(8);
12515
12516         /* allocation size */
12517         CHECK_BYTE_COUNT_SUBR(8);
12518         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12519         COUNT_BYTES_SUBR(8);
12520
12521         /* Extended File Attributes */
12522         CHECK_BYTE_COUNT_SUBR(4);
12523         offset = dissect_file_ext_attr(tvb, tree, offset);
12524         *bcp -= 4;
12525
12526         /* file name len */
12527         CHECK_BYTE_COUNT_SUBR(4);
12528         fn_len = tvb_get_letohl(tvb, offset);
12529         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12530         COUNT_BYTES_SUBR(4);
12531
12532         /* file name */
12533         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12534         CHECK_STRING_SUBR(fn);
12535         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12536                 fn);
12537         COUNT_BYTES_SUBR(fn_len);
12538
12539         if (check_col(pinfo->cinfo, COL_INFO)) {
12540                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12541                 fn);
12542         }
12543
12544         /* skip to next structure */
12545         if(neo){
12546                 padcnt = (old_offset + neo) - offset;
12547                 if (padcnt < 0) {
12548                         /*
12549                          * XXX - this is bogus; flag it?
12550                          */
12551                         padcnt = 0;
12552                 }
12553                 if (padcnt != 0) {
12554                         CHECK_BYTE_COUNT_SUBR(padcnt);
12555                         COUNT_BYTES_SUBR(padcnt);
12556                 }
12557         }
12558
12559         proto_item_append_text(item, " File: %s", fn);
12560         proto_item_set_len(item, offset-old_offset);
12561
12562         *trunc = FALSE;
12563         return offset;
12564 }
12565
12566 static int
12567 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12568     int offset, guint16 *bcp, gboolean *trunc)
12569 {
12570         int fn_len;
12571         const char *fn;
12572         int old_offset = offset;
12573         proto_item *item = NULL;
12574         proto_tree *tree = NULL;
12575         smb_info_t *si;
12576         guint32 neo;
12577         int padcnt;
12578
12579         si = (smb_info_t *)pinfo->private_data;
12580
12581         if(parent_tree){
12582                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12583                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12584                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12585         }
12586
12587         /*
12588          * We assume that the presence of a next entry offset implies the
12589          * absence of a resume key, as appears to be the case for 4.3.4.6.
12590          */
12591
12592         /* next entry offset */
12593         CHECK_BYTE_COUNT_SUBR(4);
12594         neo = tvb_get_letohl(tvb, offset);
12595         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12596         COUNT_BYTES_SUBR(4);
12597
12598         /* file index */
12599         CHECK_BYTE_COUNT_SUBR(4);
12600         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12601         COUNT_BYTES_SUBR(4);
12602
12603         /* create time */
12604         CHECK_BYTE_COUNT_SUBR(8);
12605         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12606         *bcp -= 8;
12607
12608         /* access time */
12609         CHECK_BYTE_COUNT_SUBR(8);
12610         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12611         *bcp -= 8;
12612
12613         /* last write time */
12614         CHECK_BYTE_COUNT_SUBR(8);
12615         offset = dissect_smb_64bit_time(tvb, tree, offset,
12616                 hf_smb_last_write_time);
12617         *bcp -= 8;
12618
12619         /* last change time */
12620         CHECK_BYTE_COUNT_SUBR(8);
12621         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12622         *bcp -= 8;
12623
12624         /* end of file */
12625         CHECK_BYTE_COUNT_SUBR(8);
12626         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12627         COUNT_BYTES_SUBR(8);
12628
12629         /* allocation size */
12630         CHECK_BYTE_COUNT_SUBR(8);
12631         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12632         COUNT_BYTES_SUBR(8);
12633
12634         /* Extended File Attributes */
12635         CHECK_BYTE_COUNT_SUBR(4);
12636         offset = dissect_file_ext_attr(tvb, tree, offset);
12637         *bcp -= 4;
12638
12639         /* file name len */
12640         CHECK_BYTE_COUNT_SUBR(4);
12641         fn_len = tvb_get_letohl(tvb, offset);
12642         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12643         COUNT_BYTES_SUBR(4);
12644
12645         /* ea length */
12646         CHECK_BYTE_COUNT_SUBR(4);
12647         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12648         COUNT_BYTES_SUBR(4);
12649
12650         /* file name */
12651         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12652         CHECK_STRING_SUBR(fn);
12653         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12654                 fn);
12655         COUNT_BYTES_SUBR(fn_len);
12656
12657         if (check_col(pinfo->cinfo, COL_INFO)) {
12658                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12659                 fn);
12660         }
12661
12662         /* skip to next structure */
12663         if(neo){
12664                 padcnt = (old_offset + neo) - offset;
12665                 if (padcnt < 0) {
12666                         /*
12667                          * XXX - this is bogus; flag it?
12668                          */
12669                         padcnt = 0;
12670                 }
12671                 if (padcnt != 0) {
12672                         CHECK_BYTE_COUNT_SUBR(padcnt);
12673                         COUNT_BYTES_SUBR(padcnt);
12674                 }
12675         }
12676
12677         proto_item_append_text(item, " File: %s", fn);
12678         proto_item_set_len(item, offset-old_offset);
12679
12680         *trunc = FALSE;
12681         return offset;
12682 }
12683
12684 static int
12685 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12686     int offset, guint16 *bcp, gboolean *trunc)
12687 {
12688         int fn_len, sfn_len;
12689         const char *fn, *sfn;
12690         int old_offset = offset;
12691         proto_item *item = NULL;
12692         proto_tree *tree = NULL;
12693         smb_info_t *si;
12694         guint32 neo;
12695         int padcnt;
12696
12697         si = (smb_info_t *)pinfo->private_data;
12698
12699         if(parent_tree){
12700                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12701                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12702                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12703         }
12704
12705         /*
12706          * XXX - I have not seen any of these that contain a resume
12707          * key, even though some of the requests had the "return resume
12708          * key" flag set.
12709          */
12710
12711         /* next entry offset */
12712         CHECK_BYTE_COUNT_SUBR(4);
12713         neo = tvb_get_letohl(tvb, offset);
12714         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12715         COUNT_BYTES_SUBR(4);
12716
12717         /* file index */
12718         CHECK_BYTE_COUNT_SUBR(4);
12719         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12720         COUNT_BYTES_SUBR(4);
12721
12722         /* create time */
12723         CHECK_BYTE_COUNT_SUBR(8);
12724         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12725         *bcp -= 8;
12726
12727         /* access time */
12728         CHECK_BYTE_COUNT_SUBR(8);
12729         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12730         *bcp -= 8;
12731
12732         /* last write time */
12733         CHECK_BYTE_COUNT_SUBR(8);
12734         offset = dissect_smb_64bit_time(tvb, tree, offset,
12735                 hf_smb_last_write_time);
12736         *bcp -= 8;
12737
12738         /* last change time */
12739         CHECK_BYTE_COUNT_SUBR(8);
12740         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12741         *bcp -= 8;
12742
12743         /* end of file */
12744         CHECK_BYTE_COUNT_SUBR(8);
12745         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12746         COUNT_BYTES_SUBR(8);
12747
12748         /* allocation size */
12749         CHECK_BYTE_COUNT_SUBR(8);
12750         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12751         COUNT_BYTES_SUBR(8);
12752
12753         /* Extended File Attributes */
12754         CHECK_BYTE_COUNT_SUBR(4);
12755         offset = dissect_file_ext_attr(tvb, tree, offset);
12756         *bcp -= 4;
12757
12758         /* file name len */
12759         CHECK_BYTE_COUNT_SUBR(4);
12760         fn_len = tvb_get_letohl(tvb, offset);
12761         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12762         COUNT_BYTES_SUBR(4);
12763
12764         /*
12765          * EA length.
12766          *
12767          * XXX - in one captures, this has the topmost bit set, and the
12768          * rest of the bits have the value 7.  Is the topmost bit being
12769          * set some indication that the value *isn't* the length of
12770          * the EAs?
12771          */
12772         CHECK_BYTE_COUNT_SUBR(4);
12773         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12774         COUNT_BYTES_SUBR(4);
12775
12776         /* short file name len */
12777         CHECK_BYTE_COUNT_SUBR(1);
12778         sfn_len = tvb_get_guint8(tvb, offset);
12779         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
12780         COUNT_BYTES_SUBR(1);
12781
12782         /* reserved byte */
12783         CHECK_BYTE_COUNT_SUBR(1);
12784         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12785         COUNT_BYTES_SUBR(1);
12786
12787         /* short file name */
12788         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
12789         CHECK_STRING_SUBR(sfn);
12790         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
12791                 sfn);
12792         COUNT_BYTES_SUBR(24);
12793
12794         /* file name */
12795         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12796         CHECK_STRING_SUBR(fn);
12797         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12798                 fn);
12799         COUNT_BYTES_SUBR(fn_len);
12800
12801         if (check_col(pinfo->cinfo, COL_INFO)) {
12802                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12803                 fn);
12804         }
12805
12806         /* skip to next structure */
12807         if(neo){
12808                 padcnt = (old_offset + neo) - offset;
12809                 if (padcnt < 0) {
12810                         /*
12811                          * XXX - this is bogus; flag it?
12812                          */
12813                         padcnt = 0;
12814                 }
12815                 if (padcnt != 0) {
12816                         CHECK_BYTE_COUNT_SUBR(padcnt);
12817                         COUNT_BYTES_SUBR(padcnt);
12818                 }
12819         }
12820
12821         proto_item_append_text(item, " File: %s", fn);
12822         proto_item_set_len(item, offset-old_offset);
12823
12824         *trunc = FALSE;
12825         return offset;
12826 }
12827
12828 static int
12829 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12830     int offset, guint16 *bcp, gboolean *trunc)
12831 {
12832         int fn_len;
12833         const char *fn;
12834         int old_offset = offset;
12835         proto_item *item = NULL;
12836         proto_tree *tree = NULL;
12837         smb_info_t *si;
12838         guint32 neo;
12839         int padcnt;
12840
12841         si = (smb_info_t *)pinfo->private_data;
12842
12843         if(parent_tree){
12844                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12845                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12846                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12847         }
12848
12849         /*
12850          * We assume that the presence of a next entry offset implies the
12851          * absence of a resume key, as appears to be the case for 4.3.4.6.
12852          */
12853
12854         /* next entry offset */
12855         CHECK_BYTE_COUNT_SUBR(4);
12856         neo = tvb_get_letohl(tvb, offset);
12857         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12858         COUNT_BYTES_SUBR(4);
12859
12860         /* file index */
12861         CHECK_BYTE_COUNT_SUBR(4);
12862         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12863         COUNT_BYTES_SUBR(4);
12864
12865         /* file name len */
12866         CHECK_BYTE_COUNT_SUBR(4);
12867         fn_len = tvb_get_letohl(tvb, offset);
12868         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12869         COUNT_BYTES_SUBR(4);
12870
12871         /* file name */
12872         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12873         CHECK_STRING_SUBR(fn);
12874         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12875                 fn);
12876         COUNT_BYTES_SUBR(fn_len);
12877
12878         if (check_col(pinfo->cinfo, COL_INFO)) {
12879                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12880                 fn);
12881         }
12882
12883         /* skip to next structure */
12884         if(neo){
12885                 padcnt = (old_offset + neo) - offset;
12886                 if (padcnt < 0) {
12887                         /*
12888                          * XXX - this is bogus; flag it?
12889                          */
12890                         padcnt = 0;
12891                 }
12892                 if (padcnt != 0) {
12893                         CHECK_BYTE_COUNT_SUBR(padcnt);
12894                         COUNT_BYTES_SUBR(padcnt);
12895                 }
12896         }
12897
12898         proto_item_append_text(item, " File: %s", fn);
12899         proto_item_set_len(item, offset-old_offset);
12900
12901         *trunc = FALSE;
12902         return offset;
12903 }
12904
12905 /* 4.3.4.8 - SMB_FIND_FILE_UNIX */
12906
12907 static int
12908 dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
12909                 proto_tree *tree, int offset, guint16 *bcp,
12910                 gboolean *trunc)
12911 {
12912         smb_info_t *si = pinfo->private_data;
12913         const char *fn;
12914         int fn_len;
12915
12916         /* NextEntryOffset */
12917         CHECK_BYTE_COUNT_SUBR(4);
12918         proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, TRUE);
12919         COUNT_BYTES_SUBR(4);
12920         
12921         /* ResumeKey */
12922         CHECK_BYTE_COUNT_SUBR(4);
12923         proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, TRUE);
12924         COUNT_BYTES_SUBR(4);
12925
12926         /* End of file (file size) */
12927         CHECK_BYTE_COUNT_SUBR(8);
12928         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
12929         COUNT_BYTES_SUBR(8);
12930
12931         /* Number of bytes */
12932         CHECK_BYTE_COUNT_SUBR(8);
12933         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
12934         COUNT_BYTES_SUBR(8);
12935
12936         /* Last status change */
12937         CHECK_BYTE_COUNT_SUBR(8);
12938         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
12939         *bcp -= 8;
12940
12941         /* Last access time */
12942         CHECK_BYTE_COUNT_SUBR(8);
12943         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
12944         *bcp -= 8;
12945
12946         /* Last modification time */
12947         CHECK_BYTE_COUNT_SUBR(8);
12948         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
12949         *bcp -= 8;
12950
12951         /* File owner uid */
12952         CHECK_BYTE_COUNT_SUBR(8);
12953         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
12954         COUNT_BYTES_SUBR(8);
12955
12956         /* File group gid */
12957         CHECK_BYTE_COUNT_SUBR(8);
12958         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
12959         COUNT_BYTES_SUBR(8);
12960
12961         /* File type */
12962         CHECK_BYTE_COUNT_SUBR(4);
12963         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
12964         COUNT_BYTES_SUBR(4);
12965
12966         /* Major device number */
12967         CHECK_BYTE_COUNT_SUBR(8);
12968         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
12969         COUNT_BYTES_SUBR(8);
12970
12971         /* Minor device number */
12972         CHECK_BYTE_COUNT_SUBR(8);
12973         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
12974         COUNT_BYTES_SUBR(8);
12975
12976         /* Unique id */
12977         CHECK_BYTE_COUNT_SUBR(8);
12978         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
12979         COUNT_BYTES_SUBR(8);
12980
12981         /* Permissions */
12982         CHECK_BYTE_COUNT_SUBR(8);
12983         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
12984         COUNT_BYTES_SUBR(8);
12985
12986         /* Nlinks */
12987         CHECK_BYTE_COUNT_SUBR(8);
12988         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
12989         COUNT_BYTES_SUBR(8);
12990
12991         /* Name */
12992
12993         fn = get_unicode_or_ascii_string(
12994                 tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
12995
12996         CHECK_STRING_SUBR(fn);
12997         proto_tree_add_string(
12998                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
12999         COUNT_BYTES_SUBR(fn_len);
13000
13001         /* Pad to 4 bytes */
13002
13003         if (offset % 4)
13004                 offset += 4 - (offset % 4);
13005
13006         *trunc = FALSE;
13007         return offset;
13008 }
13009
13010 /*dissect the data block for TRANS2_FIND_FIRST2*/
13011 static int
13012 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
13013     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
13014 {
13015         smb_info_t *si;
13016
13017         if(!*bcp){
13018                 return offset;
13019         }
13020
13021         si = (smb_info_t *)pinfo->private_data;
13022         switch(si->info_level){
13023         case 1:         /*Info Standard*/
13024                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
13025                     trunc);
13026                 break;
13027         case 2:         /*Info Query EA Size*/
13028                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13029                     trunc);
13030                 break;
13031         case 3:         /*Info Query EAs From List same as
13032                                 InfoQueryEASize*/
13033                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13034                     trunc);
13035                 break;
13036         case 0x0101:    /*Find File Directory Info*/
13037                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
13038                     trunc);
13039                 break;
13040         case 0x0102:    /*Find File Full Directory Info*/
13041                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
13042                     trunc);
13043                 break;
13044         case 0x0103:    /*Find File Names Info*/
13045                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
13046                     trunc);
13047                 break;
13048         case 0x0104:    /*Find File Both Directory Info*/
13049                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
13050                     trunc);
13051                 break;
13052         case 0x0202:    /*Find File UNIX*/
13053                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
13054                     trunc);
13055                 break;
13056         default:        /* unknown info level */
13057                 *trunc = FALSE;
13058                 break;
13059         }
13060         return offset;
13061 }
13062
13063
13064 static int
13065 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13066 {
13067         guint32 mask;
13068         proto_item *item = NULL;
13069         proto_tree *tree = NULL;
13070
13071         mask = tvb_get_letohl(tvb, offset);
13072
13073         if(parent_tree){
13074                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
13075                         "FS Attributes: 0x%08x", mask);
13076                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
13077         }
13078
13079         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
13080                 tvb, offset, 4, mask);
13081         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
13082                 tvb, offset, 4, mask);
13083         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
13084                 tvb, offset, 4, mask);
13085         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
13086                 tvb, offset, 4, mask);
13087         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
13088                 tvb, offset, 4, mask);
13089         proto_tree_add_boolean(tree, hf_smb_fs_attr_dim,
13090                 tvb, offset, 4, mask);
13091         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
13092                 tvb, offset, 4, mask);
13093
13094         offset += 4;
13095         return offset;
13096 }
13097
13098
13099 static int
13100 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13101 {
13102         guint32 mask;
13103         proto_item *item = NULL;
13104         proto_tree *tree = NULL;
13105
13106         mask = tvb_get_letohl(tvb, offset);
13107
13108         if(parent_tree){
13109                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
13110                         "Device Characteristics: 0x%08x", mask);
13111                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
13112         }
13113
13114         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
13115                 tvb, offset, 4, mask);
13116         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
13117                 tvb, offset, 4, mask);
13118         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
13119                 tvb, offset, 4, mask);
13120         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
13121                 tvb, offset, 4, mask);
13122         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
13123                 tvb, offset, 4, mask);
13124         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
13125                 tvb, offset, 4, mask);
13126         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
13127                 tvb, offset, 4, mask);
13128
13129         offset += 4;
13130         return offset;
13131 }
13132
13133 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
13134
13135 static const true_false_string tfs_smb_mac_access_ctrl = {
13136   "Macintosh Access Control Supported",
13137   "Macintosh Access Control Not Supported"
13138 };
13139
13140 static const true_false_string tfs_smb_mac_getset_comments = {
13141   "Macintosh Get & Set Comments Supported",
13142   "Macintosh Get & Set Comments Not Supported"
13143 };
13144
13145 static const true_false_string tfs_smb_mac_desktopdb_calls = {
13146   "Macintosh Get & Set Desktop Database Info Supported",
13147   "Macintosh Get & Set Desktop Database Info Supported"
13148 };
13149
13150 static const true_false_string tfs_smb_mac_unique_ids = {
13151   "Macintosh Unique IDs Supported",
13152   "Macintosh Unique IDs Not Supported"
13153 };
13154
13155 static const true_false_string tfs_smb_mac_streams = {
13156   "Macintosh and Streams Extensions Not Supported",
13157   "Macintosh and Streams Extensions Supported"
13158 };
13159
13160 static int
13161 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13162     int offset, guint16 *bcp)
13163 {
13164         smb_info_t *si;
13165         int fn_len, vll, fnl;
13166         const char *fn;
13167         guint support = 0;
13168         proto_item *item = NULL;
13169         proto_tree *ti = NULL;
13170
13171         if(!*bcp){
13172                 return offset;
13173         }
13174
13175         si = (smb_info_t *)pinfo->private_data;
13176         switch(si->info_level){
13177         case 1:         /* SMB_INFO_ALLOCATION */
13178                 /* filesystem id */
13179                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13180                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
13181                 COUNT_BYTES_TRANS_SUBR(4);
13182
13183                 /* sectors per unit */
13184                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13185                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13186                 COUNT_BYTES_TRANS_SUBR(4);
13187
13188                 /* units */
13189                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13190                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
13191                 COUNT_BYTES_TRANS_SUBR(4);
13192
13193                 /* avail units */
13194                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13195                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
13196                 COUNT_BYTES_TRANS_SUBR(4);
13197
13198                 /* bytes per sector, only 16bit integer here */
13199                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13200                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13201                 COUNT_BYTES_TRANS_SUBR(2);
13202
13203                 break;
13204         case 2:         /* SMB_INFO_VOLUME */
13205                 /* volume serial number */
13206                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13207                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
13208                 COUNT_BYTES_TRANS_SUBR(4);
13209
13210                 /* volume label length, only one byte here */
13211                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
13212                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
13213                 COUNT_BYTES_TRANS_SUBR(1);
13214
13215                 /* label */
13216                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
13217                 CHECK_STRING_TRANS_SUBR(fn);
13218                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13219                         fn);
13220                 COUNT_BYTES_TRANS_SUBR(fn_len);
13221
13222                 break;
13223         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
13224         case 1002:      /* SMB_FS_LABEL_INFORMATION */
13225                 /* volume label length */
13226                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13227                 vll = tvb_get_letohl(tvb, offset);
13228                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
13229                 COUNT_BYTES_TRANS_SUBR(4);
13230
13231                 /* label */
13232                 fn_len = vll;
13233                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13234                 CHECK_STRING_TRANS_SUBR(fn);
13235                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13236                         fn);
13237                 COUNT_BYTES_TRANS_SUBR(fn_len);
13238
13239                 break;
13240         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
13241         case 1001:      /* SMB_FS_VOLUME_INFORMATION */
13242                 /* create time */
13243                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13244                 offset = dissect_smb_64bit_time(tvb, tree, offset,
13245                         hf_smb_create_time);
13246                 *bcp -= 8;
13247
13248                 /* volume serial number */
13249                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13250                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
13251                 COUNT_BYTES_TRANS_SUBR(4);
13252
13253                 /* volume label length */
13254                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13255                 vll = tvb_get_letohl(tvb, offset);
13256                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
13257                 COUNT_BYTES_TRANS_SUBR(4);
13258
13259                 /* 2 reserved bytes */
13260                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13261                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
13262                 COUNT_BYTES_TRANS_SUBR(2);
13263
13264                 /* label */
13265                 fn_len = vll;
13266                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13267                 CHECK_STRING_TRANS_SUBR(fn);
13268                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13269                         fn);
13270                 COUNT_BYTES_TRANS_SUBR(fn_len);
13271
13272                 break;
13273         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
13274         case 1003:      /* SMB_FS_SIZE_INFORMATION */
13275                 /* allocation size */
13276                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13277                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13278                 COUNT_BYTES_TRANS_SUBR(8);
13279
13280                 /* free allocation units */
13281                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13282                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
13283                 COUNT_BYTES_TRANS_SUBR(8);
13284
13285                 /* sectors per unit */
13286                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13287                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13288                 COUNT_BYTES_TRANS_SUBR(4);
13289
13290                 /* bytes per sector */
13291                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13292                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
13293                 COUNT_BYTES_TRANS_SUBR(4);
13294
13295                 break;
13296         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
13297         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
13298                 /* device type */
13299                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13300                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
13301                 COUNT_BYTES_TRANS_SUBR(4);
13302
13303                 /* device characteristics */
13304                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13305                 offset = dissect_device_characteristics(tvb, tree, offset);
13306                 *bcp -= 4;
13307
13308                 break;
13309         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
13310         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
13311                 /* FS attributes */
13312                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13313                 offset = dissect_fs_attributes(tvb, tree, offset);
13314                 *bcp -= 4;
13315
13316                 /* max name len */
13317                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13318                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
13319                 COUNT_BYTES_TRANS_SUBR(4);
13320
13321                 /* fs name length */
13322                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13323                 fnl = tvb_get_letohl(tvb, offset);
13324                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
13325                 COUNT_BYTES_TRANS_SUBR(4);
13326
13327                 /* label */
13328                 fn_len = fnl;
13329                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13330                 CHECK_STRING_TRANS_SUBR(fn);
13331                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
13332                         fn);
13333                 COUNT_BYTES_TRANS_SUBR(fn_len);
13334
13335                 break;
13336         case 0x200: {   /* SMB_QUERY_CIFS_UNIX_INFO */
13337                 proto_item *item = NULL;
13338                 proto_tree *subtree = NULL;
13339                 guint32 caps_lo, caps_hi;
13340
13341                 /* MajorVersionNumber */
13342                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13343                 proto_tree_add_item(tree, hf_smb_unix_major_version, tvb, offset, 2, TRUE);
13344                 COUNT_BYTES_TRANS_SUBR(2);
13345
13346                 /* MinorVersionNumber */
13347                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13348                 proto_tree_add_item(tree, hf_smb_unix_minor_version, tvb, offset, 2, TRUE);
13349                 COUNT_BYTES_TRANS_SUBR(2);
13350
13351                 /* Capability */
13352
13353                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13354
13355                 caps_lo = tvb_get_letohl(tvb, offset);
13356                 caps_hi = tvb_get_letohl(tvb, offset + 4);
13357
13358                 if (tree) {
13359                         item = proto_tree_add_text(
13360                                 tree, tvb, offset, 8, "Capabilities: 0x%08x%08x", 
13361                                 caps_hi, caps_lo);
13362                         subtree = proto_item_add_subtree(
13363                                 item, ett_smb_unix_capabilities);
13364                 }
13365
13366                 proto_tree_add_boolean(
13367                         subtree, hf_smb_unix_capability_fcntl, tvb, offset, 8, 
13368                         caps_lo);
13369
13370                 proto_tree_add_boolean(
13371                         subtree, hf_smb_unix_capability_posix_acl, tvb, offset, 8, 
13372                         caps_lo);
13373
13374                 COUNT_BYTES_TRANS_SUBR(8);
13375
13376                 break;
13377         }
13378         case 0x301:     /* MAC_QUERY_FS_INFO */
13379                 /* Create time */
13380                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13381                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
13382                 *bcp -= 8;
13383                 /* Modify Time */
13384                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13385                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_modify_time);
13386                 *bcp -= 8;
13387                 /* Backup Time */
13388                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13389                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_backup_time);
13390                 *bcp -= 8;
13391                 /* Allocation blocks */
13392                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13393                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
13394                                     offset,
13395                                     4, TRUE);
13396                 COUNT_BYTES_TRANS_SUBR(4);
13397                 /* Allocation Block Size */
13398                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13399                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
13400                                     offset, 4, TRUE);
13401                 COUNT_BYTES_TRANS_SUBR(4);
13402                 /* Free Block Count */
13403                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13404                 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
13405                                     offset, 4, TRUE);
13406                 COUNT_BYTES_TRANS_SUBR(4);
13407                 /* Finder Info ... */
13408                 CHECK_BYTE_COUNT_TRANS_SUBR(32);
13409                 proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb,
13410                                             offset, 32,
13411                                             tvb_get_ptr(tvb, offset,32),
13412                                             "Finder Info: %s",
13413                                             tvb_format_text(tvb, offset, 32));
13414                 COUNT_BYTES_TRANS_SUBR(32);
13415                 /* Number Files */
13416                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13417                 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
13418                                     offset, 4, TRUE);
13419                 COUNT_BYTES_TRANS_SUBR(4);
13420                 /* Number of Root Directories */
13421                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13422                 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
13423                                     offset, 4, TRUE);
13424                 COUNT_BYTES_TRANS_SUBR(4);
13425                 /* Number of files */
13426                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13427                 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
13428                                     offset, 4, TRUE);
13429                 COUNT_BYTES_TRANS_SUBR(4);
13430                 /* Dir Count */
13431                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13432                 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
13433                                     offset, 4, TRUE);
13434                 COUNT_BYTES_TRANS_SUBR(4);
13435                 /* Mac Support Flags */
13436                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13437                 support = tvb_get_ntohl(tvb, offset);
13438                 item = proto_tree_add_text(tree, tvb, offset, 4,
13439                                            "Mac Support Flags: 0x%08x", support);
13440                 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
13441                 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
13442                                        tvb, offset, 4, support);
13443                 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
13444                                        tvb, offset, 4, support);
13445                 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
13446                                        tvb, offset, 4, support);
13447                 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
13448                                        tvb, offset, 4, support);
13449                 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
13450                                        tvb, offset, 4, support);
13451                 COUNT_BYTES_TRANS_SUBR(4);
13452                 break;
13453         case 1006:      /* QUERY_FS_QUOTA_INFO */
13454                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
13455                 break;
13456         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
13457                 /* allocation size */
13458                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13459                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13460                 COUNT_BYTES_TRANS_SUBR(8);
13461
13462                 /* caller free allocation units */
13463                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13464                 proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
13465                 COUNT_BYTES_TRANS_SUBR(8);
13466
13467                 /* actual free allocation units */
13468                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13469                 proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
13470                 COUNT_BYTES_TRANS_SUBR(8);
13471
13472                 /* sectors per unit */
13473                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13474                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13475                 COUNT_BYTES_TRANS_SUBR(4);
13476
13477                 /* bytes per sector */
13478                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13479                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
13480                 COUNT_BYTES_TRANS_SUBR(4);
13481                 break;
13482         case 1008: /* Query Object ID is GUID plus unknown data */ {
13483                 e_uuid_t fs_id;
13484                 char uuid_str[DCERPC_UUID_STR_LEN]; 
13485                 int uuid_str_len;
13486                 char drep = 0x10;
13487                 
13488                 CHECK_BYTE_COUNT_TRANS_SUBR(16);
13489
13490                 dcerpc_tvb_get_uuid (tvb, offset, &drep, &fs_id);
13491
13492                 uuid_str_len = snprintf(
13493                         uuid_str, DCERPC_UUID_STR_LEN, 
13494                         "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
13495                         fs_id.Data1, fs_id.Data2, fs_id.Data3,
13496                         fs_id.Data4[0], fs_id.Data4[1],
13497                         fs_id.Data4[2], fs_id.Data4[3],
13498                         fs_id.Data4[4], fs_id.Data4[5],
13499                         fs_id.Data4[6], fs_id.Data4[7]);
13500
13501                 proto_tree_add_string_format(
13502                         tree, hf_smb_fs_guid, tvb,
13503                         offset, 16, uuid_str, "GUID: %s", uuid_str);
13504
13505                 COUNT_BYTES_TRANS_SUBR(16);
13506                 break;
13507             }
13508         }
13509
13510         return offset;
13511 }
13512
13513 static int
13514 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
13515     proto_tree *parent_tree)
13516 {
13517         proto_item *item = NULL;
13518         proto_tree *tree = NULL;
13519         smb_info_t *si;
13520         smb_transact2_info_t *t2i;
13521         int count;
13522         gboolean trunc;
13523         int offset = 0;
13524         guint16 dc;
13525
13526         dc = tvb_reported_length(tvb);
13527
13528         si = (smb_info_t *)pinfo->private_data;
13529         if (si->sip != NULL)
13530                 t2i = si->sip->extra_info;
13531         else
13532                 t2i = NULL;
13533
13534         if(parent_tree){
13535                 if (t2i != NULL && t2i->subcmd != -1) {
13536                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13537                                 "%s Data",
13538                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
13539                                         "Unknown (0x%02x)"));
13540                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
13541                 } else {
13542                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13543                                 "Unknown Transaction2 Data");
13544                 }
13545         }
13546
13547         if (t2i == NULL) {
13548                 offset += dc;
13549                 return offset;
13550         }
13551         switch(t2i->subcmd){
13552         case 0x00:      /*TRANS2_OPEN2*/
13553                 /* XXX not implemented yet. See SNIA doc */
13554                 break;
13555         case 0x01:      /*TRANS2_FIND_FIRST2*/
13556                 /* returned data */
13557                 count = si->info_count;
13558
13559                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
13560                         col_append_fstr(pinfo->cinfo, COL_INFO,
13561                         ", Files:");
13562                 }
13563
13564                 while(count--){
13565                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
13566                                 offset, &dc, &trunc);
13567                         if (trunc)
13568                                 break;
13569                 }
13570                 break;
13571         case 0x02:      /*TRANS2_FIND_NEXT2*/
13572                 /* returned data */
13573                 count = si->info_count;
13574
13575                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
13576                         col_append_fstr(pinfo->cinfo, COL_INFO,
13577                         ", Files:");
13578                 }
13579
13580                 while(count--){
13581                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
13582                                 offset, &dc, &trunc);
13583                         if (trunc)
13584                                 break;
13585                 }
13586                 break;
13587         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
13588                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
13589                 break;
13590         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
13591                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
13592                 break;
13593         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
13594                 /* no data in this response */
13595                 break;
13596         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
13597                 /* identical to QUERY_PATH_INFO */
13598                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
13599                 break;
13600         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
13601                 /* no data in this response */
13602                 break;
13603         case 0x09:      /*TRANS2_FSCTL*/
13604                 /* XXX dont know how to dissect this one (yet)*/
13605
13606                 /*
13607                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13608                  * Extensions Version 3.0, Document Version 1.11,
13609                  * July 19, 1990" says this this contains a
13610                  * "File system specific return data block".
13611                  * (That means we may not be able to dissect it in any
13612                  * case.)
13613                  */
13614                 break;
13615         case 0x0a:      /*TRANS2_IOCTL2*/
13616                 /* XXX dont know how to dissect this one (yet)*/
13617
13618                 /*
13619                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13620                  * Extensions Version 3.0, Document Version 1.11,
13621                  * July 19, 1990" says this this contains a
13622                  * "Device/function specific return data block".
13623                  * (That means we may not be able to dissect it in any
13624                  * case.)
13625                  */
13626                 break;
13627         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
13628                 /* XXX dont know how to dissect this one (yet)*/
13629
13630                 /*
13631                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13632                  * Extensions Version 3.0, Document Version 1.11,
13633                  * July 19, 1990" says this this contains "the level
13634                  * dependent information about the changes which
13635                  * occurred".
13636                  */
13637                 break;
13638         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
13639                 /* XXX dont know how to dissect this one (yet)*/
13640
13641                 /*
13642                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13643                  * Extensions Version 3.0, Document Version 1.11,
13644                  * July 19, 1990" says this this contains "the level
13645                  * dependent information about the changes which
13646                  * occurred".
13647                  */
13648                 break;
13649         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
13650                 /* no data in this response */
13651                 break;
13652         case 0x0e:      /*TRANS2_SESSION_SETUP*/
13653                 /* XXX dont know how to dissect this one (yet)*/
13654                 break;
13655         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
13656                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
13657                 break;
13658         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13659                 /* the SNIA spec appears to say the response has no data */
13660                 break;
13661         case -1:
13662                 /*
13663                  * We don't know what the matching request was; don't
13664                  * bother putting anything else into the tree for the data.
13665                  */
13666                 offset += dc;
13667                 dc = 0;
13668                 break;
13669         }
13670
13671         /* ooops there were data we didnt know how to process */
13672         if(dc != 0){
13673                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
13674                 offset += dc;
13675         }
13676
13677         return offset;
13678 }
13679
13680
13681 static void
13682 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
13683 {
13684         proto_item *item = NULL;
13685         proto_tree *tree = NULL;
13686         smb_info_t *si;
13687         smb_transact2_info_t *t2i;
13688         guint16 fid;
13689         int lno;
13690         int offset = 0;
13691         int pc;
13692
13693         pc = tvb_reported_length(tvb);
13694
13695         si = (smb_info_t *)pinfo->private_data;
13696         if (si->sip != NULL)
13697                 t2i = si->sip->extra_info;
13698         else
13699                 t2i = NULL;
13700
13701         if(parent_tree){
13702                 if (t2i != NULL && t2i->subcmd != -1) {
13703                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13704                                 "%s Parameters",
13705                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
13706                                                 "Unknown (0x%02x)"));
13707                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
13708                 } else {
13709                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13710                                 "Unknown Transaction2 Parameters");
13711                 }
13712         }
13713
13714         if (t2i == NULL) {
13715                 offset += pc;
13716                 return;
13717         }
13718         switch(t2i->subcmd){
13719         case 0x00:      /*TRANS2_OPEN2*/
13720                 /* fid */
13721                 fid = tvb_get_letohs(tvb, offset);
13722                 add_fid(tvb, pinfo, tree, offset, 2, fid);
13723                 offset += 2;
13724
13725                 /*
13726                  * XXX - Microsoft Networks SMB File Sharing Protocol
13727                  * Extensions Version 3.0, Document Version 1.11,
13728                  * July 19, 1990 says that the file attributes, create
13729                  * time (which it says is the last modification time),
13730                  * data size, granted access, file type, and IPC state
13731                  * are returned only if bit 0 is set in the open flags,
13732                  * and that the EA length is returned only if bit 3
13733                  * is set in the open flags.  Does that mean that,
13734                  * at least in that SMB dialect, those fields are not
13735                  * present in the reply parameters if the bits in
13736                  * question aren't set?
13737                  */
13738
13739                 /* File Attributes */
13740                 offset = dissect_file_attributes(tvb, tree, offset, 2);
13741
13742                 /* create time */
13743                 offset = dissect_smb_datetime(tvb, tree, offset,
13744                         hf_smb_create_time,
13745                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
13746
13747                 /* data size */
13748                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
13749                 offset += 4;
13750
13751                 /* granted access */
13752                 offset = dissect_access(tvb, tree, offset, "Granted");
13753
13754                 /* File Type */
13755                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
13756                 offset += 2;
13757
13758                 /* IPC State */
13759                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
13760
13761                 /* open_action */
13762                 offset = dissect_open_action(tvb, tree, offset);
13763
13764                 /* server unique file ID */
13765                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
13766                 offset += 4;
13767
13768                 /* ea error offset, only a 16 bit integer here */
13769                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13770                 offset += 2;
13771
13772                 /* ea length */
13773                 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13774                 offset += 4;
13775
13776                 break;
13777         case 0x01:      /*TRANS2_FIND_FIRST2*/
13778                 /* Find First2 information level */
13779                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
13780
13781                 /* sid */
13782                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
13783                 offset += 2;
13784
13785                 /* search count */
13786                 si->info_count = tvb_get_letohs(tvb, offset);
13787                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13788                 offset += 2;
13789
13790                 /* end of search */
13791                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13792                 offset += 2;
13793
13794                 /* ea error offset, only a 16 bit integer here */
13795                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13796                 offset += 2;
13797
13798                 /* last name offset */
13799                 lno = tvb_get_letohs(tvb, offset);
13800                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13801                 offset += 2;
13802
13803                 break;
13804         case 0x02:      /*TRANS2_FIND_NEXT2*/
13805                 /* search count */
13806                 si->info_count = tvb_get_letohs(tvb, offset);
13807                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13808                 offset += 2;
13809
13810                 /* end of search */
13811                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13812                 offset += 2;
13813
13814                 /* ea_error_offset, only a 16 bit integer here*/
13815                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13816                 offset += 2;
13817
13818                 /* last name offset */
13819                 lno = tvb_get_letohs(tvb, offset);
13820                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13821                 offset += 2;
13822
13823                 break;
13824         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
13825                 /* no parameter block here */
13826                 break;
13827         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
13828                 /* ea_error_offset, only a 16 bit integer here*/
13829                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13830                 offset += 2;
13831
13832                 break;
13833         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
13834                 /* ea_error_offset, only a 16 bit integer here*/
13835                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13836                 offset += 2;
13837
13838                 break;
13839         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
13840                 /* ea_error_offset, only a 16 bit integer here*/
13841                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13842                 offset += 2;
13843
13844                 break;
13845         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
13846                 /* ea_error_offset, only a 16 bit integer here*/
13847                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13848                 offset += 2;
13849
13850                 break;
13851         case 0x09:      /*TRANS2_FSCTL*/
13852                 /* XXX dont know how to dissect this one (yet)*/
13853
13854                 /*
13855                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13856                  * Extensions Version 3.0, Document Version 1.11,
13857                  * July 19, 1990" says this this contains a
13858                  * "File system specific return parameter block".
13859                  * (That means we may not be able to dissect it in any
13860                  * case.)
13861                  */
13862                 break;
13863         case 0x0a:      /*TRANS2_IOCTL2*/
13864                 /* XXX dont know how to dissect this one (yet)*/
13865
13866                 /*
13867                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13868                  * Extensions Version 3.0, Document Version 1.11,
13869                  * July 19, 1990" says this this contains a
13870                  * "Device/function specific return parameter block".
13871                  * (That means we may not be able to dissect it in any
13872                  * case.)
13873                  */
13874                 break;
13875         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
13876                 /* Find Notify information level */
13877                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13878
13879                 /* Monitor handle */
13880                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
13881                 offset += 2;
13882
13883                 /* Change count */
13884                 si->info_count = tvb_get_letohs(tvb, offset);
13885                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13886                 offset += 2;
13887
13888                 /* ea_error_offset, only a 16 bit integer here*/
13889                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13890                 offset += 2;
13891
13892                 break;
13893         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
13894                 /* Find Notify information level */
13895                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13896
13897                 /* Change count */
13898                 si->info_count = tvb_get_letohs(tvb, offset);
13899                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13900                 offset += 2;
13901
13902                 /* ea_error_offset, only a 16 bit integer here*/
13903                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13904                 offset += 2;
13905
13906                 break;
13907         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
13908                 /* ea error offset, only a 16 bit integer here */
13909                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13910                 offset += 2;
13911
13912                 break;
13913         case 0x0e:      /*TRANS2_SESSION_SETUP*/
13914                 /* XXX dont know how to dissect this one (yet)*/
13915                 break;
13916         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
13917                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
13918                 break;
13919         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13920                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
13921                 break;
13922         case -1:
13923                 /*
13924                  * We don't know what the matching request was; don't
13925                  * bother putting anything else into the tree for the data.
13926                  */
13927                 offset += pc;
13928                 break;
13929         }
13930
13931         /* ooops there were data we didnt know how to process */
13932         if(offset<pc){
13933                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
13934                 offset += pc-offset;
13935         }
13936 }
13937
13938
13939 static int
13940 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13941 {
13942         guint8 sc, wc;
13943         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
13944         smb_info_t *si;
13945         smb_transact2_info_t *t2i = NULL;
13946         guint16 bc;
13947         int padcnt;
13948         gboolean dissected_trans;
13949         fragment_data *r_fd = NULL;
13950         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
13951         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
13952         gboolean save_fragmented;
13953
13954         si = (smb_info_t *)pinfo->private_data;
13955
13956         switch(si->cmd){
13957         case SMB_COM_TRANSACTION2:
13958                 /* transaction2 */
13959                 if (si->sip != NULL) {
13960                         t2i = si->sip->extra_info;
13961                 } else
13962                         t2i = NULL;
13963                 if (t2i == NULL) {
13964                         /*
13965                          * We didn't see the matching request, so we don't
13966                          * know what type of transaction this is.
13967                          */
13968                         proto_tree_add_text(tree, tvb, 0, 0,
13969                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
13970                         if (check_col(pinfo->cinfo, COL_INFO)) {
13971                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
13972                         }
13973                 } else {
13974                         si->info_level = t2i->info_level;
13975                         if (t2i->subcmd == -1) {
13976                                 /*
13977                                  * We didn't manage to extract the subcommand
13978                                  * from the matching request (perhaps because
13979                                  * the frame was short), so we don't know what
13980                                  * type of transaction this is.
13981                                  */
13982                                 proto_tree_add_text(tree, tvb, 0, 0,
13983                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
13984                                 if (check_col(pinfo->cinfo, COL_INFO)) {
13985                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
13986                                 }
13987                         } else {
13988                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
13989                                 if (check_col(pinfo->cinfo, COL_INFO)) {
13990                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
13991                                                 val_to_str(t2i->subcmd,
13992                                                         trans2_cmd_vals,
13993                                                         "<unknown (0x%02x)>"));
13994                                 }
13995                         }
13996                 }
13997                 break;
13998         }
13999
14000         WORD_COUNT;
14001
14002         /* total param count, only a 16bit integer here */
14003         tp = tvb_get_letohs(tvb, offset);
14004         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
14005         offset += 2;
14006
14007         /* total data count, only a 16 bit integer here */
14008         td = tvb_get_letohs(tvb, offset);
14009         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
14010         offset += 2;
14011
14012         /* 2 reserved bytes */
14013         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
14014         offset += 2;
14015
14016         /* param count */
14017         pc = tvb_get_letohs(tvb, offset);
14018         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
14019         offset += 2;
14020
14021         /* param offset */
14022         po = tvb_get_letohs(tvb, offset);
14023         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
14024         offset += 2;
14025
14026         /* param disp */
14027         pd = tvb_get_letohs(tvb, offset);
14028         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
14029         offset += 2;
14030
14031         /* data count */
14032         dc = tvb_get_letohs(tvb, offset);
14033         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
14034         offset += 2;
14035
14036         /* data offset */
14037         od = tvb_get_letohs(tvb, offset);
14038         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
14039         offset += 2;
14040
14041         /* data disp */
14042         dd = tvb_get_letohs(tvb, offset);
14043         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
14044         offset += 2;
14045
14046         /* setup count */
14047         sc = tvb_get_guint8(tvb, offset);
14048         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
14049         offset += 1;
14050
14051         /* reserved byte */
14052         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
14053         offset += 1;
14054
14055
14056         /* if there were any setup bytes, put them in a tvb for later */
14057         if(sc){
14058                 if((2*sc)>tvb_length_remaining(tvb, offset)){
14059                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
14060                 } else {
14061                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
14062                 }
14063                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
14064         } else {
14065                 s_tvb = NULL;
14066                 sp_tvb=NULL;
14067         }
14068         offset += 2*sc;
14069
14070
14071         BYTE_COUNT;
14072
14073
14074         /* reassembly of SMB Transaction data payload.
14075            In this section we do reassembly of both the data and parameters
14076            blocks of the SMB transaction command.
14077         */
14078         save_fragmented = pinfo->fragmented;
14079         /* do we need reassembly? */
14080         if( (td!=dc) || (tp!=pc) ){
14081                 /* oh yeah, either data or parameter section needs
14082                    reassembly
14083                 */
14084                 pinfo->fragmented = TRUE;
14085                 if(smb_trans_reassembly){
14086                         /* ...and we were told to do reassembly */
14087                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
14088                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
14089                                                              po, pc, pd, td+tp);
14090
14091                         }
14092                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
14093                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
14094                                                              od, dc, dd+tp, td+tp);
14095                         }
14096                 }
14097         }
14098
14099         /* if we got a reassembled fd structure from the reassembly routine we must
14100            create pd_tvb from it
14101         */
14102         if(r_fd){
14103                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
14104                                              r_fd->datalen);
14105                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
14106                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
14107                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
14108         }
14109
14110
14111         if(pd_tvb){
14112                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
14113                 if(tp){
14114                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
14115                 }
14116                 if(td){
14117                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
14118                 }
14119         } else {
14120                 /* It was not reassembled. Do as best as we can.
14121                  * in this case we always try to dissect the stuff if
14122                  * data and param displacement is 0. i.e. for the first
14123                  * (and maybe only) packet.
14124                  */
14125                 if( (pd==0) && (dd==0) ){
14126                         int min;
14127                         int reported_min;
14128                         min = MIN(pc,tvb_length_remaining(tvb,po));
14129                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
14130                         if(min && reported_min) {
14131                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
14132                         }
14133                         min = MIN(dc,tvb_length_remaining(tvb,od));
14134                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
14135                         if(min && reported_min) {
14136                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
14137                         }
14138                         /*
14139                          * A tvbuff containing the parameters
14140                          * and the data.
14141                          * XXX - check pc and dc as well?
14142                          */
14143                         if (tvb_length_remaining(tvb, po)){
14144                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
14145                         }
14146                 }
14147         }
14148
14149
14150
14151         /* parameters */
14152         if(po>offset){
14153                 /* We have some padding bytes.
14154                 */
14155                 padcnt = po-offset;
14156                 if (padcnt > bc)
14157                         padcnt = bc;
14158                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
14159                 COUNT_BYTES(padcnt);
14160         }
14161         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
14162                 /* TRANSACTION2 parameters*/
14163                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
14164         }
14165         COUNT_BYTES(pc);
14166
14167
14168         /* data */
14169         if(od>offset){
14170                 /* We have some initial padding bytes.
14171                 */
14172                 padcnt = od-offset;
14173                 if (padcnt > bc)
14174                         padcnt = bc;
14175                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
14176                 COUNT_BYTES(padcnt);
14177         }
14178         /*
14179          * If the data count is bigger than the count of bytes
14180          * remaining, clamp it so that the count of bytes remaining
14181          * doesn't go negative.
14182          */
14183         if (dc > bc)
14184                 dc = bc;
14185         COUNT_BYTES(dc);
14186
14187
14188
14189         /* from now on, everything is in separate tvbuffs so we dont count
14190            the bytes with COUNT_BYTES any more.
14191            neither do we reference offset any more (which by now points to the
14192            first byte AFTER this PDU */
14193
14194
14195         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
14196                 /* TRANSACTION2 parameters*/
14197                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
14198         }
14199
14200
14201         if(si->cmd==SMB_COM_TRANSACTION){
14202                 smb_transact_info_t *tri;
14203
14204                 dissected_trans = FALSE;
14205                 if (si->sip != NULL)
14206                         tri = si->sip->extra_info;
14207                 else
14208                         tri = NULL;
14209                 if (tri != NULL) {
14210                         switch(tri->subcmd){
14211
14212                         case TRANSACTION_PIPE:
14213                                 /* This function is safe to call for
14214                                    s_tvb==sp_tvb==NULL, i.e. if we don't
14215                                    know them at this point.
14216                                    It's also safe to call if "p_tvb"
14217                                    or "d_tvb" are null.
14218                                 */
14219                                 if( pd_tvb) {
14220                                         dissected_trans = dissect_pipe_smb(
14221                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
14222                                                 d_tvb, NULL, pinfo, top_tree);
14223                                 }
14224                                 break;
14225
14226                         case TRANSACTION_MAILSLOT:
14227                                 /* This one should be safe to call
14228                                    even if s_tvb and sp_tvb is NULL
14229                                 */
14230                                 if(d_tvb){
14231                                         dissected_trans = dissect_mailslot_smb(
14232                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
14233                                                 top_tree);
14234                                 }
14235                                 break;
14236                         }
14237                 }
14238                 if (!dissected_trans) {
14239                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
14240                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
14241                 }
14242         }
14243
14244
14245         if( (p_tvb==0) && (d_tvb==0) ){
14246                 if(check_col(pinfo->cinfo, COL_INFO)){
14247                         col_append_str(pinfo->cinfo, COL_INFO,
14248                                        "[transact continuation]");
14249                 }
14250         }
14251
14252         pinfo->fragmented = save_fragmented;
14253         END_OF_SMB
14254
14255         return offset;
14256 }
14257
14258
14259 static int
14260 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14261 {
14262         guint8 wc;
14263         guint16 bc;
14264
14265         WORD_COUNT;
14266
14267         /* Monitor handle */
14268         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
14269         offset += 2;
14270
14271         BYTE_COUNT;
14272
14273         END_OF_SMB
14274
14275         return offset;
14276 }
14277
14278 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14279    END Transaction/Transaction2 Primary and secondary requests
14280    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
14281
14282
14283 static int
14284 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14285 {
14286         guint8 wc;
14287         guint16 bc;
14288
14289         WORD_COUNT;
14290
14291         if (wc != 0) {
14292                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
14293                 offset += wc*2;
14294         }
14295
14296         BYTE_COUNT;
14297
14298         if (bc != 0) {
14299                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
14300                 offset += bc;
14301                 bc = 0;
14302         }
14303
14304         END_OF_SMB
14305
14306         return offset;
14307 }
14308
14309 typedef struct _smb_function {
14310        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14311        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14312 } smb_function;
14313
14314 static smb_function smb_dissector[256] = {
14315   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
14316   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
14317   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
14318   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
14319   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
14320   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
14321   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
14322   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
14323   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
14324   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
14325   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
14326   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
14327   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
14328   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
14329   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
14330   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
14331
14332   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
14333   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
14334   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
14335   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
14336   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
14337   /* 0x15 */  {dissect_unknown, dissect_unknown},
14338   /* 0x16 */  {dissect_unknown, dissect_unknown},
14339   /* 0x17 */  {dissect_unknown, dissect_unknown},
14340   /* 0x18 */  {dissect_unknown, dissect_unknown},
14341   /* 0x19 */  {dissect_unknown, dissect_unknown},
14342   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
14343   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
14344   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
14345   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
14346   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
14347   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
14348
14349   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
14350   /* 0x21 */  {dissect_unknown, dissect_unknown},
14351   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
14352   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
14353   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
14354   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
14355   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
14356   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
14357   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
14358   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
14359   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
14360   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
14361   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
14362   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
14363   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
14364   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
14365
14366   /* 0x30 */  {dissect_unknown, dissect_unknown},
14367   /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
14368   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
14369   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
14370   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
14371   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
14372   /* 0x36 */  {dissect_unknown, dissect_unknown},
14373   /* 0x37 */  {dissect_unknown, dissect_unknown},
14374   /* 0x38 */  {dissect_unknown, dissect_unknown},
14375   /* 0x39 */  {dissect_unknown, dissect_unknown},
14376   /* 0x3a */  {dissect_unknown, dissect_unknown},
14377   /* 0x3b */  {dissect_unknown, dissect_unknown},
14378   /* 0x3c */  {dissect_unknown, dissect_unknown},
14379   /* 0x3d */  {dissect_unknown, dissect_unknown},
14380   /* 0x3e */  {dissect_unknown, dissect_unknown},
14381   /* 0x3f */  {dissect_unknown, dissect_unknown},
14382
14383   /* 0x40 */  {dissect_unknown, dissect_unknown},
14384   /* 0x41 */  {dissect_unknown, dissect_unknown},
14385   /* 0x42 */  {dissect_unknown, dissect_unknown},
14386   /* 0x43 */  {dissect_unknown, dissect_unknown},
14387   /* 0x44 */  {dissect_unknown, dissect_unknown},
14388   /* 0x45 */  {dissect_unknown, dissect_unknown},
14389   /* 0x46 */  {dissect_unknown, dissect_unknown},
14390   /* 0x47 */  {dissect_unknown, dissect_unknown},
14391   /* 0x48 */  {dissect_unknown, dissect_unknown},
14392   /* 0x49 */  {dissect_unknown, dissect_unknown},
14393   /* 0x4a */  {dissect_unknown, dissect_unknown},
14394   /* 0x4b */  {dissect_unknown, dissect_unknown},
14395   /* 0x4c */  {dissect_unknown, dissect_unknown},
14396   /* 0x4d */  {dissect_unknown, dissect_unknown},
14397   /* 0x4e */  {dissect_unknown, dissect_unknown},
14398   /* 0x4f */  {dissect_unknown, dissect_unknown},
14399
14400   /* 0x50 */  {dissect_unknown, dissect_unknown},
14401   /* 0x51 */  {dissect_unknown, dissect_unknown},
14402   /* 0x52 */  {dissect_unknown, dissect_unknown},
14403   /* 0x53 */  {dissect_unknown, dissect_unknown},
14404   /* 0x54 */  {dissect_unknown, dissect_unknown},
14405   /* 0x55 */  {dissect_unknown, dissect_unknown},
14406   /* 0x56 */  {dissect_unknown, dissect_unknown},
14407   /* 0x57 */  {dissect_unknown, dissect_unknown},
14408   /* 0x58 */  {dissect_unknown, dissect_unknown},
14409   /* 0x59 */  {dissect_unknown, dissect_unknown},
14410   /* 0x5a */  {dissect_unknown, dissect_unknown},
14411   /* 0x5b */  {dissect_unknown, dissect_unknown},
14412   /* 0x5c */  {dissect_unknown, dissect_unknown},
14413   /* 0x5d */  {dissect_unknown, dissect_unknown},
14414   /* 0x5e */  {dissect_unknown, dissect_unknown},
14415   /* 0x5f */  {dissect_unknown, dissect_unknown},
14416
14417   /* 0x60 */  {dissect_unknown, dissect_unknown},
14418   /* 0x61 */  {dissect_unknown, dissect_unknown},
14419   /* 0x62 */  {dissect_unknown, dissect_unknown},
14420   /* 0x63 */  {dissect_unknown, dissect_unknown},
14421   /* 0x64 */  {dissect_unknown, dissect_unknown},
14422   /* 0x65 */  {dissect_unknown, dissect_unknown},
14423   /* 0x66 */  {dissect_unknown, dissect_unknown},
14424   /* 0x67 */  {dissect_unknown, dissect_unknown},
14425   /* 0x68 */  {dissect_unknown, dissect_unknown},
14426   /* 0x69 */  {dissect_unknown, dissect_unknown},
14427   /* 0x6a */  {dissect_unknown, dissect_unknown},
14428   /* 0x6b */  {dissect_unknown, dissect_unknown},
14429   /* 0x6c */  {dissect_unknown, dissect_unknown},
14430   /* 0x6d */  {dissect_unknown, dissect_unknown},
14431   /* 0x6e */  {dissect_unknown, dissect_unknown},
14432   /* 0x6f */  {dissect_unknown, dissect_unknown},
14433
14434   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
14435   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
14436   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
14437   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
14438   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
14439   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
14440   /* 0x76 */  {dissect_unknown, dissect_unknown},
14441   /* 0x77 */  {dissect_unknown, dissect_unknown},
14442   /* 0x78 */  {dissect_unknown, dissect_unknown},
14443   /* 0x79 */  {dissect_unknown, dissect_unknown},
14444   /* 0x7a */  {dissect_unknown, dissect_unknown},
14445   /* 0x7b */  {dissect_unknown, dissect_unknown},
14446   /* 0x7c */  {dissect_unknown, dissect_unknown},
14447   /* 0x7d */  {dissect_unknown, dissect_unknown},
14448   /* 0x7e */  {dissect_unknown, dissect_unknown},
14449   /* 0x7f */  {dissect_unknown, dissect_unknown},
14450
14451   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
14452   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
14453   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
14454   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
14455   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
14456   /* 0x85 */  {dissect_unknown, dissect_unknown},
14457   /* 0x86 */  {dissect_unknown, dissect_unknown},
14458   /* 0x87 */  {dissect_unknown, dissect_unknown},
14459   /* 0x88 */  {dissect_unknown, dissect_unknown},
14460   /* 0x89 */  {dissect_unknown, dissect_unknown},
14461   /* 0x8a */  {dissect_unknown, dissect_unknown},
14462   /* 0x8b */  {dissect_unknown, dissect_unknown},
14463   /* 0x8c */  {dissect_unknown, dissect_unknown},
14464   /* 0x8d */  {dissect_unknown, dissect_unknown},
14465   /* 0x8e */  {dissect_unknown, dissect_unknown},
14466   /* 0x8f */  {dissect_unknown, dissect_unknown},
14467
14468   /* 0x90 */  {dissect_unknown, dissect_unknown},
14469   /* 0x91 */  {dissect_unknown, dissect_unknown},
14470   /* 0x92 */  {dissect_unknown, dissect_unknown},
14471   /* 0x93 */  {dissect_unknown, dissect_unknown},
14472   /* 0x94 */  {dissect_unknown, dissect_unknown},
14473   /* 0x95 */  {dissect_unknown, dissect_unknown},
14474   /* 0x96 */  {dissect_unknown, dissect_unknown},
14475   /* 0x97 */  {dissect_unknown, dissect_unknown},
14476   /* 0x98 */  {dissect_unknown, dissect_unknown},
14477   /* 0x99 */  {dissect_unknown, dissect_unknown},
14478   /* 0x9a */  {dissect_unknown, dissect_unknown},
14479   /* 0x9b */  {dissect_unknown, dissect_unknown},
14480   /* 0x9c */  {dissect_unknown, dissect_unknown},
14481   /* 0x9d */  {dissect_unknown, dissect_unknown},
14482   /* 0x9e */  {dissect_unknown, dissect_unknown},
14483   /* 0x9f */  {dissect_unknown, dissect_unknown},
14484
14485   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
14486   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
14487   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
14488   /* 0xa3 */  {dissect_unknown, dissect_unknown},
14489   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
14490   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
14491   /* 0xa6 */  {dissect_unknown, dissect_unknown},
14492   /* 0xa7 */  {dissect_unknown, dissect_unknown},
14493   /* 0xa8 */  {dissect_unknown, dissect_unknown},
14494   /* 0xa9 */  {dissect_unknown, dissect_unknown},
14495   /* 0xaa */  {dissect_unknown, dissect_unknown},
14496   /* 0xab */  {dissect_unknown, dissect_unknown},
14497   /* 0xac */  {dissect_unknown, dissect_unknown},
14498   /* 0xad */  {dissect_unknown, dissect_unknown},
14499   /* 0xae */  {dissect_unknown, dissect_unknown},
14500   /* 0xaf */  {dissect_unknown, dissect_unknown},
14501
14502   /* 0xb0 */  {dissect_unknown, dissect_unknown},
14503   /* 0xb1 */  {dissect_unknown, dissect_unknown},
14504   /* 0xb2 */  {dissect_unknown, dissect_unknown},
14505   /* 0xb3 */  {dissect_unknown, dissect_unknown},
14506   /* 0xb4 */  {dissect_unknown, dissect_unknown},
14507   /* 0xb5 */  {dissect_unknown, dissect_unknown},
14508   /* 0xb6 */  {dissect_unknown, dissect_unknown},
14509   /* 0xb7 */  {dissect_unknown, dissect_unknown},
14510   /* 0xb8 */  {dissect_unknown, dissect_unknown},
14511   /* 0xb9 */  {dissect_unknown, dissect_unknown},
14512   /* 0xba */  {dissect_unknown, dissect_unknown},
14513   /* 0xbb */  {dissect_unknown, dissect_unknown},
14514   /* 0xbc */  {dissect_unknown, dissect_unknown},
14515   /* 0xbd */  {dissect_unknown, dissect_unknown},
14516   /* 0xbe */  {dissect_unknown, dissect_unknown},
14517   /* 0xbf */  {dissect_unknown, dissect_unknown},
14518
14519   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
14520   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
14521   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
14522   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
14523   /* 0xc4 */  {dissect_unknown, dissect_unknown},
14524   /* 0xc5 */  {dissect_unknown, dissect_unknown},
14525   /* 0xc6 */  {dissect_unknown, dissect_unknown},
14526   /* 0xc7 */  {dissect_unknown, dissect_unknown},
14527   /* 0xc8 */  {dissect_unknown, dissect_unknown},
14528   /* 0xc9 */  {dissect_unknown, dissect_unknown},
14529   /* 0xca */  {dissect_unknown, dissect_unknown},
14530   /* 0xcb */  {dissect_unknown, dissect_unknown},
14531   /* 0xcc */  {dissect_unknown, dissect_unknown},
14532   /* 0xcd */  {dissect_unknown, dissect_unknown},
14533   /* 0xce */  {dissect_unknown, dissect_unknown},
14534   /* 0xcf */  {dissect_unknown, dissect_unknown},
14535
14536   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
14537   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
14538   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
14539   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
14540   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
14541   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
14542   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
14543   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
14544   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
14545   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
14546   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
14547   /* 0xdb */  {dissect_unknown, dissect_unknown},
14548   /* 0xdc */  {dissect_unknown, dissect_unknown},
14549   /* 0xdd */  {dissect_unknown, dissect_unknown},
14550   /* 0xde */  {dissect_unknown, dissect_unknown},
14551   /* 0xdf */  {dissect_unknown, dissect_unknown},
14552
14553   /* 0xe0 */  {dissect_unknown, dissect_unknown},
14554   /* 0xe1 */  {dissect_unknown, dissect_unknown},
14555   /* 0xe2 */  {dissect_unknown, dissect_unknown},
14556   /* 0xe3 */  {dissect_unknown, dissect_unknown},
14557   /* 0xe4 */  {dissect_unknown, dissect_unknown},
14558   /* 0xe5 */  {dissect_unknown, dissect_unknown},
14559   /* 0xe6 */  {dissect_unknown, dissect_unknown},
14560   /* 0xe7 */  {dissect_unknown, dissect_unknown},
14561   /* 0xe8 */  {dissect_unknown, dissect_unknown},
14562   /* 0xe9 */  {dissect_unknown, dissect_unknown},
14563   /* 0xea */  {dissect_unknown, dissect_unknown},
14564   /* 0xeb */  {dissect_unknown, dissect_unknown},
14565   /* 0xec */  {dissect_unknown, dissect_unknown},
14566   /* 0xed */  {dissect_unknown, dissect_unknown},
14567   /* 0xee */  {dissect_unknown, dissect_unknown},
14568   /* 0xef */  {dissect_unknown, dissect_unknown},
14569
14570   /* 0xf0 */  {dissect_unknown, dissect_unknown},
14571   /* 0xf1 */  {dissect_unknown, dissect_unknown},
14572   /* 0xf2 */  {dissect_unknown, dissect_unknown},
14573   /* 0xf3 */  {dissect_unknown, dissect_unknown},
14574   /* 0xf4 */  {dissect_unknown, dissect_unknown},
14575   /* 0xf5 */  {dissect_unknown, dissect_unknown},
14576   /* 0xf6 */  {dissect_unknown, dissect_unknown},
14577   /* 0xf7 */  {dissect_unknown, dissect_unknown},
14578   /* 0xf8 */  {dissect_unknown, dissect_unknown},
14579   /* 0xf9 */  {dissect_unknown, dissect_unknown},
14580   /* 0xfa */  {dissect_unknown, dissect_unknown},
14581   /* 0xfb */  {dissect_unknown, dissect_unknown},
14582   /* 0xfc */  {dissect_unknown, dissect_unknown},
14583   /* 0xfd */  {dissect_unknown, dissect_unknown},
14584   /* 0xfe */  {dissect_unknown, dissect_unknown},
14585   /* 0xff */  {dissect_unknown, dissect_unknown},
14586 };
14587
14588 static int
14589 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
14590 {
14591         smb_info_t *si;
14592
14593         si = pinfo->private_data;
14594         if(cmd!=0xff){
14595                 proto_item *cmd_item;
14596                 proto_tree *cmd_tree;
14597                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14598
14599                 if (check_col(pinfo->cinfo, COL_INFO)) {
14600                         if(first_pdu){
14601                                 col_append_fstr(pinfo->cinfo, COL_INFO,
14602                                         "%s %s",
14603                                         decode_smb_name(cmd),
14604                                         (si->request)? "Request" : "Response");
14605                         } else {
14606                                 col_append_fstr(pinfo->cinfo, COL_INFO,
14607                                         "; %s",
14608                                         decode_smb_name(cmd));
14609                         }
14610
14611                 }
14612
14613                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
14614                         "%s %s (0x%02x)",
14615                         decode_smb_name(cmd),
14616                         (si->request)?"Request":"Response",
14617                         cmd);
14618
14619                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
14620
14621                 dissector = (si->request)?
14622                         smb_dissector[cmd].request:smb_dissector[cmd].response;
14623
14624                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
14625                 proto_item_set_end(cmd_item, tvb, offset);
14626         }
14627         return offset;
14628 }
14629
14630
14631 /* NOTE: this value_string array will also be used to access data directly by
14632  * index instead of val_to_str() since
14633  * 1, the array will always span every value from 0x00 to 0xff and
14634  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
14635  * This means that this value_string array MUST always
14636  * 1, contain all entries 0x00 to 0xff
14637  * 2, all entries must be in order.
14638  */
14639 const value_string smb_cmd_vals[] = {
14640   { 0x00, "Create Directory" },
14641   { 0x01, "Delete Directory" },
14642   { 0x02, "Open" },
14643   { 0x03, "Create" },
14644   { 0x04, "Close" },
14645   { 0x05, "Flush" },
14646   { 0x06, "Delete" },
14647   { 0x07, "Rename" },
14648   { 0x08, "Query Information" },
14649   { 0x09, "Set Information" },
14650   { 0x0A, "Read" },
14651   { 0x0B, "Write" },
14652   { 0x0C, "Lock Byte Range" },
14653   { 0x0D, "Unlock Byte Range" },
14654   { 0x0E, "Create Temp" },
14655   { 0x0F, "Create New" },
14656   { 0x10, "Check Directory" },
14657   { 0x11, "Process Exit" },
14658   { 0x12, "Seek" },
14659   { 0x13, "Lock And Read" },
14660   { 0x14, "Write And Unlock" },
14661   { 0x15, "unknown-0x15" },
14662   { 0x16, "unknown-0x16" },
14663   { 0x17, "unknown-0x17" },
14664   { 0x18, "unknown-0x18" },
14665   { 0x19, "unknown-0x19" },
14666   { 0x1A, "Read Raw" },
14667   { 0x1B, "Read MPX" },
14668   { 0x1C, "Read MPX Secondary" },
14669   { 0x1D, "Write Raw" },
14670   { 0x1E, "Write MPX" },
14671   { 0x1F, "Write MPX Secondary" },
14672   { 0x20, "Write Complete" },
14673   { 0x21, "unknown-0x21" },
14674   { 0x22, "Set Information2" },
14675   { 0x23, "Query Information2" },
14676   { 0x24, "Locking AndX" },
14677   { 0x25, "Trans" },
14678   { 0x26, "Trans Secondary" },
14679   { 0x27, "IOCTL" },
14680   { 0x28, "IOCTL Secondary" },
14681   { 0x29, "Copy" },
14682   { 0x2A, "Move" },
14683   { 0x2B, "Echo" },
14684   { 0x2C, "Write And Close" },
14685   { 0x2D, "Open AndX" },
14686   { 0x2E, "Read AndX" },
14687   { 0x2F, "Write AndX" },
14688   { 0x30, "unknown-0x30" },
14689   { 0x31, "Close And Tree Disconnect" },
14690   { 0x32, "Trans2" },
14691   { 0x33, "Trans2 Secondary" },
14692   { 0x34, "Find Close2" },
14693   { 0x35, "Find Notify Close" },
14694   { 0x36, "unknown-0x36" },
14695   { 0x37, "unknown-0x37" },
14696   { 0x38, "unknown-0x38" },
14697   { 0x39, "unknown-0x39" },
14698   { 0x3A, "unknown-0x3A" },
14699   { 0x3B, "unknown-0x3B" },
14700   { 0x3C, "unknown-0x3C" },
14701   { 0x3D, "unknown-0x3D" },
14702   { 0x3E, "unknown-0x3E" },
14703   { 0x3F, "unknown-0x3F" },
14704   { 0x40, "unknown-0x40" },
14705   { 0x41, "unknown-0x41" },
14706   { 0x42, "unknown-0x42" },
14707   { 0x43, "unknown-0x43" },
14708   { 0x44, "unknown-0x44" },
14709   { 0x45, "unknown-0x45" },
14710   { 0x46, "unknown-0x46" },
14711   { 0x47, "unknown-0x47" },
14712   { 0x48, "unknown-0x48" },
14713   { 0x49, "unknown-0x49" },
14714   { 0x4A, "unknown-0x4A" },
14715   { 0x4B, "unknown-0x4B" },
14716   { 0x4C, "unknown-0x4C" },
14717   { 0x4D, "unknown-0x4D" },
14718   { 0x4E, "unknown-0x4E" },
14719   { 0x4F, "unknown-0x4F" },
14720   { 0x50, "unknown-0x50" },
14721   { 0x51, "unknown-0x51" },
14722   { 0x52, "unknown-0x52" },
14723   { 0x53, "unknown-0x53" },
14724   { 0x54, "unknown-0x54" },
14725   { 0x55, "unknown-0x55" },
14726   { 0x56, "unknown-0x56" },
14727   { 0x57, "unknown-0x57" },
14728   { 0x58, "unknown-0x58" },
14729   { 0x59, "unknown-0x59" },
14730   { 0x5A, "unknown-0x5A" },
14731   { 0x5B, "unknown-0x5B" },
14732   { 0x5C, "unknown-0x5C" },
14733   { 0x5D, "unknown-0x5D" },
14734   { 0x5E, "unknown-0x5E" },
14735   { 0x5F, "unknown-0x5F" },
14736   { 0x60, "unknown-0x60" },
14737   { 0x61, "unknown-0x61" },
14738   { 0x62, "unknown-0x62" },
14739   { 0x63, "unknown-0x63" },
14740   { 0x64, "unknown-0x64" },
14741   { 0x65, "unknown-0x65" },
14742   { 0x66, "unknown-0x66" },
14743   { 0x67, "unknown-0x67" },
14744   { 0x68, "unknown-0x68" },
14745   { 0x69, "unknown-0x69" },
14746   { 0x6A, "unknown-0x6A" },
14747   { 0x6B, "unknown-0x6B" },
14748   { 0x6C, "unknown-0x6C" },
14749   { 0x6D, "unknown-0x6D" },
14750   { 0x6E, "unknown-0x6E" },
14751   { 0x6F, "unknown-0x6F" },
14752   { 0x70, "Tree Connect" },
14753   { 0x71, "Tree Disconnect" },
14754   { 0x72, "Negotiate Protocol" },
14755   { 0x73, "Session Setup AndX" },
14756   { 0x74, "Logoff AndX" },
14757   { 0x75, "Tree Connect AndX" },
14758   { 0x76, "unknown-0x76" },
14759   { 0x77, "unknown-0x77" },
14760   { 0x78, "unknown-0x78" },
14761   { 0x79, "unknown-0x79" },
14762   { 0x7A, "unknown-0x7A" },
14763   { 0x7B, "unknown-0x7B" },
14764   { 0x7C, "unknown-0x7C" },
14765   { 0x7D, "unknown-0x7D" },
14766   { 0x7E, "unknown-0x7E" },
14767   { 0x7F, "unknown-0x7F" },
14768   { 0x80, "Query Information Disk" },
14769   { 0x81, "Search" },
14770   { 0x82, "Find" },
14771   { 0x83, "Find Unique" },
14772   { 0x84, "Find Close" },
14773   { 0x85, "unknown-0x85" },
14774   { 0x86, "unknown-0x86" },
14775   { 0x87, "unknown-0x87" },
14776   { 0x88, "unknown-0x88" },
14777   { 0x89, "unknown-0x89" },
14778   { 0x8A, "unknown-0x8A" },
14779   { 0x8B, "unknown-0x8B" },
14780   { 0x8C, "unknown-0x8C" },
14781   { 0x8D, "unknown-0x8D" },
14782   { 0x8E, "unknown-0x8E" },
14783   { 0x8F, "unknown-0x8F" },
14784   { 0x90, "unknown-0x90" },
14785   { 0x91, "unknown-0x91" },
14786   { 0x92, "unknown-0x92" },
14787   { 0x93, "unknown-0x93" },
14788   { 0x94, "unknown-0x94" },
14789   { 0x95, "unknown-0x95" },
14790   { 0x96, "unknown-0x96" },
14791   { 0x97, "unknown-0x97" },
14792   { 0x98, "unknown-0x98" },
14793   { 0x99, "unknown-0x99" },
14794   { 0x9A, "unknown-0x9A" },
14795   { 0x9B, "unknown-0x9B" },
14796   { 0x9C, "unknown-0x9C" },
14797   { 0x9D, "unknown-0x9D" },
14798   { 0x9E, "unknown-0x9E" },
14799   { 0x9F, "unknown-0x9F" },
14800   { 0xA0, "NT Trans" },
14801   { 0xA1, "NT Trans Secondary" },
14802   { 0xA2, "NT Create AndX" },
14803   { 0xA3, "unknown-0xA3" },
14804   { 0xA4, "NT Cancel" },
14805   { 0xA5, "NT Rename" },
14806   { 0xA6, "unknown-0xA6" },
14807   { 0xA7, "unknown-0xA7" },
14808   { 0xA8, "unknown-0xA8" },
14809   { 0xA9, "unknown-0xA9" },
14810   { 0xAA, "unknown-0xAA" },
14811   { 0xAB, "unknown-0xAB" },
14812   { 0xAC, "unknown-0xAC" },
14813   { 0xAD, "unknown-0xAD" },
14814   { 0xAE, "unknown-0xAE" },
14815   { 0xAF, "unknown-0xAF" },
14816   { 0xB0, "unknown-0xB0" },
14817   { 0xB1, "unknown-0xB1" },
14818   { 0xB2, "unknown-0xB2" },
14819   { 0xB3, "unknown-0xB3" },
14820   { 0xB4, "unknown-0xB4" },
14821   { 0xB5, "unknown-0xB5" },
14822   { 0xB6, "unknown-0xB6" },
14823   { 0xB7, "unknown-0xB7" },
14824   { 0xB8, "unknown-0xB8" },
14825   { 0xB9, "unknown-0xB9" },
14826   { 0xBA, "unknown-0xBA" },
14827   { 0xBB, "unknown-0xBB" },
14828   { 0xBC, "unknown-0xBC" },
14829   { 0xBD, "unknown-0xBD" },
14830   { 0xBE, "unknown-0xBE" },
14831   { 0xBF, "unknown-0xBF" },
14832   { 0xC0, "Open Print File" },
14833   { 0xC1, "Write Print File" },
14834   { 0xC2, "Close Print File" },
14835   { 0xC3, "Get Print Queue" },
14836   { 0xC4, "unknown-0xC4" },
14837   { 0xC5, "unknown-0xC5" },
14838   { 0xC6, "unknown-0xC6" },
14839   { 0xC7, "unknown-0xC7" },
14840   { 0xC8, "unknown-0xC8" },
14841   { 0xC9, "unknown-0xC9" },
14842   { 0xCA, "unknown-0xCA" },
14843   { 0xCB, "unknown-0xCB" },
14844   { 0xCC, "unknown-0xCC" },
14845   { 0xCD, "unknown-0xCD" },
14846   { 0xCE, "unknown-0xCE" },
14847   { 0xCF, "unknown-0xCF" },
14848   { 0xD0, "Send Single Block Message" },
14849   { 0xD1, "Send Broadcast Message" },
14850   { 0xD2, "Forward User Name" },
14851   { 0xD3, "Cancel Forward" },
14852   { 0xD4, "Get Machine Name" },
14853   { 0xD5, "Send Start of Multi-block Message" },
14854   { 0xD6, "Send End of Multi-block Message" },
14855   { 0xD7, "Send Text of Multi-block Message" },
14856   { 0xD8, "SMBreadbulk" },
14857   { 0xD9, "SMBwritebulk" },
14858   { 0xDA, "SMBwritebulkdata" },
14859   { 0xDB, "unknown-0xDB" },
14860   { 0xDC, "unknown-0xDC" },
14861   { 0xDD, "unknown-0xDD" },
14862   { 0xDE, "unknown-0xDE" },
14863   { 0xDF, "unknown-0xDF" },
14864   { 0xE0, "unknown-0xE0" },
14865   { 0xE1, "unknown-0xE1" },
14866   { 0xE2, "unknown-0xE2" },
14867   { 0xE3, "unknown-0xE3" },
14868   { 0xE4, "unknown-0xE4" },
14869   { 0xE5, "unknown-0xE5" },
14870   { 0xE6, "unknown-0xE6" },
14871   { 0xE7, "unknown-0xE7" },
14872   { 0xE8, "unknown-0xE8" },
14873   { 0xE9, "unknown-0xE9" },
14874   { 0xEA, "unknown-0xEA" },
14875   { 0xEB, "unknown-0xEB" },
14876   { 0xEC, "unknown-0xEC" },
14877   { 0xED, "unknown-0xED" },
14878   { 0xEE, "unknown-0xEE" },
14879   { 0xEF, "unknown-0xEF" },
14880   { 0xF0, "unknown-0xF0" },
14881   { 0xF1, "unknown-0xF1" },
14882   { 0xF2, "unknown-0xF2" },
14883   { 0xF3, "unknown-0xF3" },
14884   { 0xF4, "unknown-0xF4" },
14885   { 0xF5, "unknown-0xF5" },
14886   { 0xF6, "unknown-0xF6" },
14887   { 0xF7, "unknown-0xF7" },
14888   { 0xF8, "unknown-0xF8" },
14889   { 0xF9, "unknown-0xF9" },
14890   { 0xFA, "unknown-0xFA" },
14891   { 0xFB, "unknown-0xFB" },
14892   { 0xFC, "unknown-0xFC" },
14893   { 0xFD, "unknown-0xFD" },
14894   { 0xFE, "SMBinvalid" },
14895   { 0xFF, "unknown-0xFF" },
14896   { 0x00, NULL },
14897 };
14898
14899 static char *decode_smb_name(unsigned char cmd)
14900 {
14901   return(smb_cmd_vals[cmd].strptr);
14902 }
14903
14904
14905
14906 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14907  * Everything TVBUFFIFIED above this line
14908  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
14909
14910
14911 static void
14912 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
14913 {
14914         conv_tables_t *ct = ctarg;
14915
14916         if (ct->unmatched)
14917                 g_hash_table_destroy(ct->unmatched);
14918         if (ct->matched)
14919                 g_hash_table_destroy(ct->matched);
14920         if (ct->tid_service)
14921                 g_hash_table_destroy(ct->tid_service);
14922 }
14923
14924 static void
14925 smb_init_protocol(void)
14926 {
14927         if (smb_saved_info_key_chunk)
14928                 g_mem_chunk_destroy(smb_saved_info_key_chunk);
14929         if (smb_saved_info_chunk)
14930                 g_mem_chunk_destroy(smb_saved_info_chunk);
14931         if (smb_nt_transact_info_chunk)
14932                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
14933         if (smb_transact2_info_chunk)
14934                 g_mem_chunk_destroy(smb_transact2_info_chunk);
14935         if (smb_transact_info_chunk)
14936                 g_mem_chunk_destroy(smb_transact_info_chunk);
14937
14938         /*
14939          * Free the hash tables attached to the conversation table
14940          * structures, and then free the list of conversation table
14941          * data structures (which doesn't free the data structures
14942          * themselves; that's done by destroying the chunk from
14943          * which they were allocated).
14944          */
14945         if (conv_tables) {
14946                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
14947                 g_slist_free(conv_tables);
14948                 conv_tables = NULL;
14949         }
14950
14951         /*
14952          * Now destroy the chunk from which the conversation table
14953          * structures were allocated.
14954          */
14955         if (conv_tables_chunk)
14956                 g_mem_chunk_destroy(conv_tables_chunk);
14957
14958         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
14959             sizeof(smb_saved_info_t),
14960             smb_saved_info_init_count * sizeof(smb_saved_info_t),
14961             G_ALLOC_ONLY);
14962         smb_saved_info_key_chunk = g_mem_chunk_new("smb_saved_info_key_chunk",
14963             sizeof(smb_saved_info_key_t),
14964             smb_saved_info_init_count * sizeof(smb_saved_info_key_t),
14965             G_ALLOC_ONLY);
14966         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
14967             sizeof(smb_nt_transact_info_t),
14968             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
14969             G_ALLOC_ONLY);
14970         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
14971             sizeof(smb_transact2_info_t),
14972             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
14973             G_ALLOC_ONLY);
14974         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
14975             sizeof(smb_transact_info_t),
14976             smb_transact_info_init_count * sizeof(smb_transact_info_t),
14977             G_ALLOC_ONLY);
14978         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
14979             sizeof(conv_tables_t),
14980             conv_tables_count * sizeof(conv_tables_t),
14981             G_ALLOC_ONLY);
14982 }
14983
14984 static const value_string errcls_types[] = {
14985   { SMB_SUCCESS, "Success"},
14986   { SMB_ERRDOS, "DOS Error"},
14987   { SMB_ERRSRV, "Server Error"},
14988   { SMB_ERRHRD, "Hardware Error"},
14989   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
14990   { 0, NULL }
14991 };
14992
14993 const value_string DOS_errors[] = {
14994   {0, "Success"},
14995   {SMBE_insufficientbuffer, "Insufficient buffer"},
14996   {SMBE_badfunc, "Invalid function (or system call)"},
14997   {SMBE_badfile, "File not found (pathname error)"},
14998   {SMBE_badpath, "Directory not found"},
14999   {SMBE_nofids, "Too many open files"},
15000   {SMBE_noaccess, "Access denied"},
15001   {SMBE_badfid, "Invalid fid"},
15002   {SMBE_nomem,  "Out of memory"},
15003   {SMBE_badmem, "Invalid memory block address"},
15004   {SMBE_badenv, "Invalid environment"},
15005   {SMBE_badaccess, "Invalid open mode"},
15006   {SMBE_baddata, "Invalid data (only from ioctl call)"},
15007   {SMBE_res, "Reserved error code?"},
15008   {SMBE_baddrive, "Invalid drive"},
15009   {SMBE_remcd, "Attempt to delete current directory"},
15010   {SMBE_diffdevice, "Rename/move across different filesystems"},
15011   {SMBE_nofiles, "No more files found in file search"},
15012   {SMBE_badshare, "Share mode on file conflict with open mode"},
15013   {SMBE_lock, "Lock request conflicts with existing lock"},
15014   {SMBE_unsup, "Request unsupported, returned by Win 95"},
15015   {SMBE_nosuchshare, "Requested share does not exist"},
15016   {SMBE_filexists, "File in operation already exists"},
15017   {SMBE_cannotopen, "Cannot open the file specified"},
15018   {SMBE_unknownlevel, "Unknown info level"},
15019   {SMBE_invalidname, "Invalid name"},
15020   {SMBE_badpipe, "Named pipe invalid"},
15021   {SMBE_pipebusy, "All instances of pipe are busy"},
15022   {SMBE_pipeclosing, "Named pipe close in progress"},
15023   {SMBE_notconnected, "No process on other end of named pipe"},
15024   {SMBE_moredata, "More data to be returned"},
15025   {SMBE_baddirectory,  "Invalid directory name in a path."},
15026   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
15027   {SMBE_eas_nsup, "Extended attributes not supported"},
15028   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
15029   {SMBE_unknownipc, "Unknown IPC Operation"},
15030   {SMBE_noipc, "Don't support ipc"},
15031   {SMBE_alreadyexists, "File already exists"},
15032   {SMBE_unknownprinterdriver, "Unknown printer driver"},
15033   {SMBE_invalidprintername, "Invalid printer name"},
15034   {SMBE_printeralreadyexists, "Printer already exists"},
15035   {SMBE_invaliddatatype, "Invalid data type"},
15036   {SMBE_invalidenvironment, "Invalid environment"},
15037   {SMBE_printerdriverinuse, "Printer driver in use"},
15038   {SMBE_invalidparam, "Invalid parameter"},
15039   {SMBE_invalidformsize, "Invalid form size"},
15040   {SMBE_invalidsecuritydescriptor, "Invalid security descriptor"},
15041   {SMBE_invalidowner, "Invalid owner"},
15042   {SMBE_nomoreitems, "No more items"},
15043   {SMBE_serverunavailable, "Server unavailable"},
15044   {0, NULL}
15045   };
15046
15047 /* Error codes for the ERRSRV class */
15048
15049 static const value_string SRV_errors[] = {
15050   {SMBE_error, "Non specific error code"},
15051   {SMBE_badpw, "Bad password"},
15052   {SMBE_badtype, "Reserved"},
15053   {SMBE_access, "No permissions to perform the requested operation"},
15054   {SMBE_invnid, "TID invalid"},
15055   {SMBE_invnetname, "Invalid network name. Service not found"},
15056   {SMBE_invdevice, "Invalid device"},
15057   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
15058   {SMBE_qfull, "Print queue full"},
15059   {SMBE_qtoobig, "Queued item too big"},
15060   {SMBE_qeof, "EOF on print queue dump"},
15061   {SMBE_invpfid, "Invalid print file in smb_fid"},
15062   {SMBE_smbcmd, "Unrecognised command"},
15063   {SMBE_srverror, "SMB server internal error"},
15064   {SMBE_filespecs, "Fid and pathname invalid combination"},
15065   {SMBE_badlink, "Bad link in request ???"},
15066   {SMBE_badpermits, "Access specified for a file is not valid"},
15067   {SMBE_badpid, "Bad process id in request"},
15068   {SMBE_setattrmode, "Attribute mode invalid"},
15069   {SMBE_paused, "Message server paused"},
15070   {SMBE_msgoff, "Not receiving messages"},
15071   {SMBE_noroom, "No room for message"},
15072   {SMBE_rmuns, "Too many remote usernames"},
15073   {SMBE_timeout, "Operation timed out"},
15074   {SMBE_noresource, "No resources currently available for request."},
15075   {SMBE_toomanyuids, "Too many userids"},
15076   {SMBE_baduid, "Bad userid"},
15077   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
15078   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
15079   {SMBE_contMPX, "Resume MPX mode"},
15080   {SMBE_badPW, "Bad Password???"},
15081   {SMBE_nosupport, "Operation not supported"},
15082   { 0, NULL}
15083 };
15084
15085 /* Error codes for the ERRHRD class */
15086
15087 static const value_string HRD_errors[] = {
15088   {SMBE_nowrite, "Read only media"},
15089   {SMBE_badunit, "Unknown device"},
15090   {SMBE_notready, "Drive not ready"},
15091   {SMBE_badcmd, "Unknown command"},
15092   {SMBE_data, "Data (CRC) error"},
15093   {SMBE_badreq, "Bad request structure length"},
15094   {SMBE_seek, "Seek error"},
15095   {SMBE_badmedia, "Unknown media type"},
15096   {SMBE_badsector, "Sector not found"},
15097   {SMBE_nopaper, "Printer out of paper"},
15098   {SMBE_write, "Write fault"},
15099   {SMBE_read, "Read fault"},
15100   {SMBE_general, "General failure"},
15101   {SMBE_badshare, "A open conflicts with an existing open"},
15102   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
15103   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
15104   {SMBE_FCBunavail, "No FCBs are available to process request"},
15105   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
15106   {SMBE_diskfull, "Disk full???"},
15107   {0, NULL}
15108 };
15109
15110 static char *decode_smb_error(guint8 errcls, guint16 errcode)
15111 {
15112
15113   switch (errcls) {
15114
15115   case SMB_SUCCESS:
15116
15117     return("No Error");   /* No error ??? */
15118     break;
15119
15120   case SMB_ERRDOS:
15121
15122     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
15123     break;
15124
15125   case SMB_ERRSRV:
15126
15127     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
15128     break;
15129
15130   case SMB_ERRHRD:
15131
15132     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
15133     break;
15134
15135   default:
15136
15137     return("Unknown error class!");
15138
15139   }
15140
15141 }
15142
15143
15144 /* These are the MS country codes from
15145
15146         http://www.unicode.org/unicode/onlinedat/countries.html
15147
15148    For countries that share the same number, I choose to use only the
15149    name of the largest country. Apologies for this. If this offends you,
15150    here is the table to change that.
15151
15152    This also includes the code of 0 for "Default", which isn't in
15153    that list, but is in Microsoft's SDKs and the Cygnus "winnls.h"
15154    header file.  Presumably it means "don't override the setting
15155    on the user's machine".
15156
15157    Future versions of Microsoft's "winnls.h" header file might include
15158    additional codes; the current version matches the Unicode Consortium's
15159    table.
15160 */
15161 const value_string ms_country_codes[] = {
15162         {  0,   "Default"},
15163         {  1,   "USA"},
15164         {  2,   "Canada"},
15165         {  7,   "Russia"},
15166         { 20,   "Egypt"},
15167         { 27,   "South Africa"},
15168         { 30,   "Greece"},
15169         { 31,   "Netherlands"},
15170         { 32,   "Belgium"},
15171         { 33,   "France"},
15172         { 34,   "Spain"},
15173         { 36,   "Hungary"},
15174         { 39,   "Italy"},
15175         { 40,   "Romania"},
15176         { 41,   "Switzerland"},
15177         { 43,   "Austria"},
15178         { 44,   "United Kingdom"},
15179         { 45,   "Denmark"},
15180         { 46,   "Sweden"},
15181         { 47,   "Norway"},
15182         { 48,   "Poland"},
15183         { 49,   "Germany"},
15184         { 51,   "Peru"},
15185         { 52,   "Mexico"},
15186         { 54,   "Argentina"},
15187         { 55,   "Brazil"},
15188         { 56,   "Chile"},
15189         { 57,   "Colombia"},
15190         { 58,   "Venezuela"},
15191         { 60,   "Malaysia"},
15192         { 61,   "Australia"},
15193         { 62,   "Indonesia"},
15194         { 63,   "Philippines"},
15195         { 64,   "New Zealand"},
15196         { 65,   "Singapore"},
15197         { 66,   "Thailand"},
15198         { 81,   "Japan"},
15199         { 82,   "South Korea"},
15200         { 84,   "Viet Nam"},
15201         { 86,   "China"},
15202         { 90,   "Turkey"},
15203         { 91,   "India"},
15204         { 92,   "Pakistan"},
15205         {212,   "Morocco"},
15206         {213,   "Algeria"},
15207         {216,   "Tunisia"},
15208         {218,   "Libya"},
15209         {254,   "Kenya"},
15210         {263,   "Zimbabwe"},
15211         {298,   "Faroe Islands"},
15212         {351,   "Portugal"},
15213         {352,   "Luxembourg"},
15214         {353,   "Ireland"},
15215         {354,   "Iceland"},
15216         {355,   "Albania"},
15217         {358,   "Finland"},
15218         {359,   "Bulgaria"},
15219         {370,   "Lithuania"},
15220         {371,   "Latvia"},
15221         {372,   "Estonia"},
15222         {374,   "Armenia"},
15223         {375,   "Belarus"},
15224         {380,   "Ukraine"},
15225         {381,   "Serbia"},
15226         {385,   "Croatia"},
15227         {386,   "Slovenia"},
15228         {389,   "Macedonia"},
15229         {420,   "Czech Republic"},
15230         {421,   "Slovak Republic"},
15231         {501,   "Belize"},
15232         {502,   "Guatemala"},
15233         {503,   "El Salvador"},
15234         {504,   "Honduras"},
15235         {505,   "Nicaragua"},
15236         {506,   "Costa Rica"},
15237         {507,   "Panama"},
15238         {591,   "Bolivia"},
15239         {593,   "Ecuador"},
15240         {595,   "Paraguay"},
15241         {598,   "Uruguay"},
15242         {673,   "Brunei Darussalam"},
15243         {852,   "Hong Kong"},
15244         {853,   "Macau"},
15245         {886,   "Taiwan"},
15246         {960,   "Maldives"},
15247         {961,   "Lebanon"},
15248         {962,   "Jordan"},
15249         {963,   "Syria"},
15250         {964,   "Iraq"},
15251         {965,   "Kuwait"},
15252         {966,   "Saudi Arabia"},
15253         {967,   "Yemen"},
15254         {968,   "Oman"},
15255         {971,   "United Arab Emirates"},
15256         {972,   "Israel"},
15257         {973,   "Bahrain"},
15258         {974,   "Qatar"},
15259         {976,   "Mongolia"},
15260         {981,   "Iran"},
15261         {994,   "Azerbaijan"},
15262         {995,   "Georgia"},
15263         {996,   "Kyrgyzstan"},
15264
15265         {0,     NULL}
15266 };
15267
15268 /*
15269  * NT error codes.
15270  *
15271  * From
15272  *
15273  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
15274  */
15275 const value_string NT_errors[] = {
15276   { 0x00000000, "STATUS_SUCCESS" },
15277   { 0x00000000, "STATUS_WAIT_0" },
15278   { 0x00000001, "STATUS_WAIT_1" },
15279   { 0x00000002, "STATUS_WAIT_2" },
15280   { 0x00000003, "STATUS_WAIT_3" },
15281   { 0x0000003F, "STATUS_WAIT_63" },
15282   { 0x00000080, "STATUS_ABANDONED" },
15283   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
15284   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
15285   { 0x000000C0, "STATUS_USER_APC" },
15286   { 0x00000100, "STATUS_KERNEL_APC" },
15287   { 0x00000101, "STATUS_ALERTED" },
15288   { 0x00000102, "STATUS_TIMEOUT" },
15289   { 0x00000103, "STATUS_PENDING" },
15290   { 0x00000104, "STATUS_REPARSE" },
15291   { 0x00000105, "STATUS_MORE_ENTRIES" },
15292   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
15293   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
15294   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
15295   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
15296   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
15297   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
15298   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
15299   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
15300   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
15301   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
15302   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
15303   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
15304   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
15305   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
15306   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
15307   { 0x00000116, "STATUS_CRASH_DUMP" },
15308   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
15309   { 0x00000118, "STATUS_REPARSE_OBJECT" },
15310   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
15311   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
15312   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
15313   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
15314   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
15315   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
15316   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
15317   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
15318   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
15319   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
15320   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
15321   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
15322   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
15323   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
15324   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
15325   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
15326   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
15327   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
15328   { 0x40000012, "STATUS_EVENT_DONE" },
15329   { 0x40000013, "STATUS_EVENT_PENDING" },
15330   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
15331   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
15332   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
15333   { 0x40000017, "STATUS_WAS_UNLOCKED" },
15334   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
15335   { 0x40000019, "STATUS_WAS_LOCKED" },
15336   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
15337   { 0x4000001B, "STATUS_ALREADY_WIN32" },
15338   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
15339   { 0x4000001D, "STATUS_WX86_CONTINUE" },
15340   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
15341   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
15342   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
15343   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
15344   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
15345   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
15346   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
15347   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
15348   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
15349   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
15350   { 0x80000003, "STATUS_BREAKPOINT" },
15351   { 0x80000004, "STATUS_SINGLE_STEP" },
15352   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
15353   { 0x80000006, "STATUS_NO_MORE_FILES" },
15354   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
15355   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
15356   { 0x8000000B, "STATUS_NO_INHERITANCE" },
15357   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
15358   { 0x8000000D, "STATUS_PARTIAL_COPY" },
15359   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
15360   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
15361   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
15362   { 0x80000011, "STATUS_DEVICE_BUSY" },
15363   { 0x80000012, "STATUS_NO_MORE_EAS" },
15364   { 0x80000013, "STATUS_INVALID_EA_NAME" },
15365   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
15366   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
15367   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
15368   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
15369   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
15370   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
15371   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
15372   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
15373   { 0x8000001D, "STATUS_BUS_RESET" },
15374   { 0x8000001E, "STATUS_END_OF_MEDIA" },
15375   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
15376   { 0x80000020, "STATUS_MEDIA_CHECK" },
15377   { 0x80000021, "STATUS_SETMARK_DETECTED" },
15378   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
15379   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
15380   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
15381   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
15382   { 0x80000026, "STATUS_LONGJUMP" },
15383   { 0x80040111, "MAPI_E_LOGON_FAILED" },
15384   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
15385   { 0x80090301, "SEC_E_INVALID_HANDLE" },
15386   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
15387   { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
15388   { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
15389   { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
15390   { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
15391   { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
15392   { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
15393   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
15394   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
15395   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
15396   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
15397   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
15398   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
15399   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
15400   { 0xC0000008, "STATUS_INVALID_HANDLE" },
15401   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
15402   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
15403   { 0xC000000B, "STATUS_INVALID_CID" },
15404   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
15405   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
15406   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
15407   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
15408   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
15409   { 0xC0000011, "STATUS_END_OF_FILE" },
15410   { 0xC0000012, "STATUS_WRONG_VOLUME" },
15411   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
15412   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
15413   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
15414   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
15415   { 0xC0000017, "STATUS_NO_MEMORY" },
15416   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
15417   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
15418   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
15419   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
15420   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
15421   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
15422   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
15423   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
15424   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
15425   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
15426   { 0xC0000022, "STATUS_ACCESS_DENIED" },
15427   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
15428   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
15429   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
15430   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
15431   { 0xC0000027, "STATUS_UNWIND" },
15432   { 0xC0000028, "STATUS_BAD_STACK" },
15433   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
15434   { 0xC000002A, "STATUS_NOT_LOCKED" },
15435   { 0xC000002B, "STATUS_PARITY_ERROR" },
15436   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
15437   { 0xC000002D, "STATUS_NOT_COMMITTED" },
15438   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
15439   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
15440   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
15441   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
15442   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
15443   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
15444   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
15445   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
15446   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
15447   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
15448   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
15449   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
15450   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
15451   { 0xC000003C, "STATUS_DATA_OVERRUN" },
15452   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
15453   { 0xC000003E, "STATUS_DATA_ERROR" },
15454   { 0xC000003F, "STATUS_CRC_ERROR" },
15455   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
15456   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
15457   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
15458   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
15459   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
15460   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
15461   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
15462   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
15463   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
15464   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
15465   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
15466   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
15467   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
15468   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
15469   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
15470   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
15471   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
15472   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
15473   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
15474   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
15475   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
15476   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
15477   { 0xC0000056, "STATUS_DELETE_PENDING" },
15478   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
15479   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
15480   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
15481   { 0xC000005A, "STATUS_INVALID_OWNER" },
15482   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
15483   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
15484   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
15485   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
15486   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
15487   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
15488   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
15489   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
15490   { 0xC0000063, "STATUS_USER_EXISTS" },
15491   { 0xC0000064, "STATUS_NO_SUCH_USER" },
15492   { 0xC0000065, "STATUS_GROUP_EXISTS" },
15493   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
15494   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
15495   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
15496   { 0xC0000069, "STATUS_LAST_ADMIN" },
15497   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
15498   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
15499   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
15500   { 0xC000006D, "STATUS_LOGON_FAILURE" },
15501   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
15502   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
15503   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
15504   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
15505   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
15506   { 0xC0000073, "STATUS_NONE_MAPPED" },
15507   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
15508   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
15509   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
15510   { 0xC0000077, "STATUS_INVALID_ACL" },
15511   { 0xC0000078, "STATUS_INVALID_SID" },
15512   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
15513   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
15514   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
15515   { 0xC000007C, "STATUS_NO_TOKEN" },
15516   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
15517   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
15518   { 0xC000007F, "STATUS_DISK_FULL" },
15519   { 0xC0000080, "STATUS_SERVER_DISABLED" },
15520   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
15521   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
15522   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
15523   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
15524   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
15525   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
15526   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
15527   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
15528   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
15529   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
15530   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
15531   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
15532   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
15533   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
15534   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
15535   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
15536   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
15537   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
15538   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
15539   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
15540   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
15541   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
15542   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
15543   { 0xC0000098, "STATUS_FILE_INVALID" },
15544   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
15545   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
15546   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
15547   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
15548   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
15549   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
15550   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
15551   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
15552   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
15553   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
15554   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
15555   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
15556   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
15557   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
15558   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
15559   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
15560   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
15561   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
15562   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
15563   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
15564   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
15565   { 0xC00000AE, "STATUS_PIPE_BUSY" },
15566   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
15567   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
15568   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
15569   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
15570   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
15571   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
15572   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
15573   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
15574   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
15575   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
15576   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
15577   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
15578   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
15579   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
15580   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
15581   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
15582   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
15583   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
15584   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
15585   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
15586   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
15587   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
15588   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
15589   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
15590   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
15591   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
15592   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
15593   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
15594   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
15595   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
15596   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
15597   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
15598   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
15599   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
15600   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
15601   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
15602   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
15603   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
15604   { 0xC00000D5, "STATUS_FILE_RENAMED" },
15605   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
15606   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
15607   { 0xC00000D8, "STATUS_CANT_WAIT" },
15608   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
15609   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
15610   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
15611   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
15612   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
15613   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
15614   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
15615   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
15616   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
15617   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
15618   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
15619   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
15620   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
15621   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
15622   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
15623   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
15624   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
15625   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
15626   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
15627   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
15628   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
15629   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
15630   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
15631   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
15632   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
15633   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
15634   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
15635   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
15636   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
15637   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
15638   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
15639   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
15640   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
15641   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
15642   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
15643   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
15644   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
15645   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
15646   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
15647   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
15648   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
15649   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
15650   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
15651   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
15652   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
15653   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
15654   { 0xC0000107, "STATUS_FILES_OPEN" },
15655   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
15656   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
15657   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
15658   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
15659   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
15660   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
15661   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
15662   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
15663   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
15664   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
15665   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
15666   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
15667   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
15668   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
15669   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
15670   { 0xC0000117, "STATUS_NO_LDT" },
15671   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
15672   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
15673   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
15674   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
15675   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
15676   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
15677   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
15678   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
15679   { 0xC0000120, "STATUS_CANCELLED" },
15680   { 0xC0000121, "STATUS_CANNOT_DELETE" },
15681   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
15682   { 0xC0000123, "STATUS_FILE_DELETED" },
15683   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
15684   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
15685   { 0xC0000126, "STATUS_SPECIAL_USER" },
15686   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
15687   { 0xC0000128, "STATUS_FILE_CLOSED" },
15688   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
15689   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
15690   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
15691   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
15692   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
15693   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
15694   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
15695   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
15696   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
15697   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
15698   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
15699   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
15700   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
15701   { 0xC0000136, "STATUS_OPEN_FAILED" },
15702   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
15703   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
15704   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
15705   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
15706   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
15707   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
15708   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
15709   { 0xC000013E, "STATUS_LINK_FAILED" },
15710   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
15711   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
15712   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
15713   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
15714   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
15715   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
15716   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
15717   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
15718   { 0xC0000147, "STATUS_NO_PAGEFILE" },
15719   { 0xC0000148, "STATUS_INVALID_LEVEL" },
15720   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
15721   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
15722   { 0xC000014B, "STATUS_PIPE_BROKEN" },
15723   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
15724   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
15725   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
15726   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
15727   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
15728   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
15729   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
15730   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
15731   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
15732   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
15733   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
15734   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
15735   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
15736   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
15737   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
15738   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
15739   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
15740   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
15741   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
15742   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
15743   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
15744   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
15745   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
15746   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
15747   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
15748   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
15749   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
15750   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
15751   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
15752   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
15753   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
15754   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
15755   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
15756   { 0xC000016D, "STATUS_FT_ORPHANING" },
15757   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
15758   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
15759   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
15760   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
15761   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
15762   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
15763   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
15764   { 0xC0000178, "STATUS_NO_MEDIA" },
15765   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
15766   { 0xC000017B, "STATUS_INVALID_MEMBER" },
15767   { 0xC000017C, "STATUS_KEY_DELETED" },
15768   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
15769   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
15770   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
15771   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
15772   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
15773   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
15774   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
15775   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
15776   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
15777   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
15778   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
15779   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
15780   { 0xC0000189, "STATUS_TOO_LATE" },
15781   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
15782   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
15783   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
15784   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
15785   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
15786   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
15787   { 0xC0000190, "STATUS_TRUST_FAILURE" },
15788   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
15789   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
15790   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
15791   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
15792   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
15793   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
15794   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
15795   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
15796   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
15797   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
15798   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
15799   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
15800   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
15801   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
15802   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
15803   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
15804   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
15805   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
15806   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
15807   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
15808   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
15809   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
15810   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
15811   { 0xC000020D, "STATUS_CONNECTION_RESET" },
15812   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
15813   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
15814   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
15815   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
15816   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
15817   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
15818   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
15819   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
15820   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
15821   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
15822   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
15823   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
15824   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
15825   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
15826   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
15827   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
15828   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
15829   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
15830   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
15831   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
15832   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
15833   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
15834   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
15835   { 0xC0000225, "STATUS_NOT_FOUND" },
15836   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
15837   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
15838   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
15839   { 0xC0000229, "STATUS_FAIL_CHECK" },
15840   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
15841   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
15842   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
15843   { 0xC000022D, "STATUS_RETRY" },
15844   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
15845   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
15846   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
15847   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
15848   { 0xC0000232, "STATUS_INVALID_VARIANT" },
15849   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
15850   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
15851   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
15852   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
15853   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
15854   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
15855   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
15856   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
15857   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
15858   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
15859   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
15860   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
15861   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
15862   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
15863   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
15864   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
15865   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
15866   { 0xC0000244, "STATUS_AUDIT_FAILED" },
15867   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
15868   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
15869   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
15870   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
15871   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
15872   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
15873   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
15874   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
15875   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
15876   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
15877   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
15878   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
15879   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
15880   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
15881   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
15882   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
15883   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
15884   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
15885   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
15886   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
15887   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
15888   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
15889   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
15890   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
15891   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
15892   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
15893   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
15894   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
15895   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
15896   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
15897   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
15898   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
15899   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
15900   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
15901   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
15902   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
15903   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
15904   { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
15905   { 0xC0000272, "STATUS_NO_MATCH" },
15906   { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
15907   { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
15908   { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
15909   { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
15910   { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
15911   { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
15912   { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
15913   { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
15914   { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
15915   { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
15916   { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
15917   { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
15918   { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
15919   { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
15920   { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
15921   { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
15922   { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
15923   { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
15924   { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
15925   { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
15926   { 0xC000028E, "STATUS_NO_EFS" },
15927   { 0xC000028F, "STATUS_WRONG_EFS" },
15928   { 0xC0000290, "STATUS_NO_USER_KEYS" },
15929   { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
15930   { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
15931   { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
15932   { 0x40000294, "STATUS_WAKE_SYSTEM" },
15933   { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
15934   { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
15935   { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
15936   { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
15937   { 0xC0000299, "STATUS_SHARED_POLICY" },
15938   { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
15939   { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
15940   { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
15941   { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
15942   { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
15943   { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
15944   { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
15945   { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
15946   { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
15947   { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
15948   { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
15949   { 0xC00002A5, "STATUS_DS_BUSY" },
15950   { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
15951   { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
15952   { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
15953   { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
15954   { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
15955   { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
15956   { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
15957   { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
15958   { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
15959   { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
15960   { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
15961   { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
15962   { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
15963   { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
15964   { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
15965   { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
15966   { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
15967   { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
15968   { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
15969   { 0xC00002B9, "STATUS_NOINTERFACE" },
15970   { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
15971   { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
15972   { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
15973   { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
15974   { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
15975   { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
15976   { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
15977   { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
15978   { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
15979   { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
15980   { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
15981   { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
15982   { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
15983   { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
15984   { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
15985   { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
15986   { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
15987   { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
15988   { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
15989   { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
15990   { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
15991   { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
15992   { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
15993   { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
15994   { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
15995   { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
15996   { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
15997   { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
15998   { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
15999   { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
16000   { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
16001   { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
16002   { 0xC00002E1, "STATUS_DS_CANT_START" },
16003   { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
16004   { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
16005   { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
16006   { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
16007   { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
16008   { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
16009   { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
16010   { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
16011   { 0xC0009898, "STATUS_WOW_ASSERTION" },
16012   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
16013   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
16014   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
16015   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
16016   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
16017   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
16018   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
16019   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
16020   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
16021   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
16022   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
16023   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
16024   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
16025   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
16026   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
16027   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
16028   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
16029   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
16030   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
16031   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
16032   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
16033   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
16034   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
16035   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
16036   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
16037   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
16038   { 0xC002001B, "RPC_NT_CALL_FAILED" },
16039   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
16040   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
16041   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
16042   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
16043   { 0xC0020022, "RPC_NT_INVALID_TAG" },
16044   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
16045   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
16046   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
16047   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
16048   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
16049   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
16050   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
16051   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
16052   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
16053   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
16054   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
16055   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
16056   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
16057   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
16058   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
16059   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
16060   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
16061   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
16062   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
16063   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
16064   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
16065   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
16066   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
16067   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
16068   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
16069   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
16070   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
16071   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
16072   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
16073   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
16074   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
16075   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
16076   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
16077   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
16078   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
16079   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
16080   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
16081   { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
16082   { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
16083   { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
16084   { 0xC002100A, "RPC_P_SEND_FAILED" },
16085   { 0xC002100B, "RPC_P_TIMEOUT" },
16086   { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
16087   { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
16088   { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
16089   { 0xC0021015, "RPC_P_THREAD_LISTENING" },
16090   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
16091   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
16092   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
16093   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
16094   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
16095   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
16096   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
16097   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
16098   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
16099   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
16100   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
16101   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
16102   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
16103   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
16104   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
16105   { 0xC002004C, "EPT_NT_CANT_CREATE" },
16106   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
16107   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
16108   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
16109   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
16110   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
16111   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
16112   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
16113   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
16114   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
16115   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
16116   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
16117   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
16118   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
16119   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
16120   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
16121   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
16122   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
16123   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
16124   { 0,          NULL }
16125 };
16126
16127
16128
16129 static const true_false_string tfs_smb_flags_lock = {
16130         "Lock&Read, Write&Unlock are supported",
16131         "Lock&Read, Write&Unlock are not supported"
16132 };
16133 static const true_false_string tfs_smb_flags_receive_buffer = {
16134         "Receive buffer has been posted",
16135         "Receive buffer has not been posted"
16136 };
16137 static const true_false_string tfs_smb_flags_caseless = {
16138         "Path names are caseless",
16139         "Path names are case sensitive"
16140 };
16141 static const true_false_string tfs_smb_flags_canon = {
16142         "Pathnames are canonicalized",
16143         "Pathnames are not canonicalized"
16144 };
16145 static const true_false_string tfs_smb_flags_oplock = {
16146         "OpLock requested/granted",
16147         "OpLock not requested/granted"
16148 };
16149 static const true_false_string tfs_smb_flags_notify = {
16150         "Notify client on all modifications",
16151         "Notify client only on open"
16152 };
16153 static const true_false_string tfs_smb_flags_response = {
16154         "Message is a response to the client/redirector",
16155         "Message is a request to the server"
16156 };
16157
16158 static int
16159 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16160 {
16161         guint8 mask;
16162         proto_item *item = NULL;
16163         proto_tree *tree = NULL;
16164
16165         mask = tvb_get_guint8(tvb, offset);
16166
16167         if(parent_tree){
16168                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
16169                         "Flags: 0x%02x", mask);
16170                 tree = proto_item_add_subtree(item, ett_smb_flags);
16171         }
16172         proto_tree_add_boolean(tree, hf_smb_flags_response,
16173                 tvb, offset, 1, mask);
16174         proto_tree_add_boolean(tree, hf_smb_flags_notify,
16175                 tvb, offset, 1, mask);
16176         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
16177                 tvb, offset, 1, mask);
16178         proto_tree_add_boolean(tree, hf_smb_flags_canon,
16179                 tvb, offset, 1, mask);
16180         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
16181                 tvb, offset, 1, mask);
16182         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
16183                 tvb, offset, 1, mask);
16184         proto_tree_add_boolean(tree, hf_smb_flags_lock,
16185                 tvb, offset, 1, mask);
16186         offset += 1;
16187         return offset;
16188 }
16189
16190
16191
16192 static const true_false_string tfs_smb_flags2_long_names_allowed = {
16193         "Long file names are allowed in the response",
16194         "Long file names are not allowed in the response"
16195 };
16196 static const true_false_string tfs_smb_flags2_ea = {
16197         "Extended attributes are supported",
16198         "Extended attributes are not supported"
16199 };
16200 static const true_false_string tfs_smb_flags2_sec_sig = {
16201         "Security signatures are supported",
16202         "Security signatures are not supported"
16203 };
16204 static const true_false_string tfs_smb_flags2_long_names_used = {
16205         "Path names in request are long file names",
16206         "Path names in request are not long file names"
16207 };
16208 static const true_false_string tfs_smb_flags2_esn = {
16209         "Extended security negotiation is supported",
16210         "Extended security negotiation is not supported"
16211 };
16212 static const true_false_string tfs_smb_flags2_dfs = {
16213         "Resolve pathnames with Dfs",
16214         "Don't resolve pathnames with Dfs"
16215 };
16216 static const true_false_string tfs_smb_flags2_roe = {
16217         "Permit reads if execute-only",
16218         "Don't permit reads if execute-only"
16219 };
16220 static const true_false_string tfs_smb_flags2_nt_error = {
16221         "Error codes are NT error codes",
16222         "Error codes are DOS error codes"
16223 };
16224 static const true_false_string tfs_smb_flags2_string = {
16225         "Strings are Unicode",
16226         "Strings are ASCII"
16227 };
16228 static int
16229 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16230 {
16231         guint16 mask;
16232         proto_item *item = NULL;
16233         proto_tree *tree = NULL;
16234
16235         mask = tvb_get_letohs(tvb, offset);
16236
16237         if(parent_tree){
16238                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
16239                         "Flags2: 0x%04x", mask);
16240                 tree = proto_item_add_subtree(item, ett_smb_flags2);
16241         }
16242
16243         proto_tree_add_boolean(tree, hf_smb_flags2_string,
16244                 tvb, offset, 2, mask);
16245         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
16246                 tvb, offset, 2, mask);
16247         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
16248                 tvb, offset, 2, mask);
16249         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
16250                 tvb, offset, 2, mask);
16251         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
16252                 tvb, offset, 2, mask);
16253         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
16254                 tvb, offset, 2, mask);
16255         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
16256                 tvb, offset, 2, mask);
16257         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
16258                 tvb, offset, 2, mask);
16259         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
16260                 tvb, offset, 2, mask);
16261
16262         offset += 2;
16263         return offset;
16264 }
16265
16266
16267
16268 #define SMB_FLAGS_DIRN 0x80
16269
16270
16271 static void
16272 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16273 {
16274         int offset = 0;
16275         proto_item *item = NULL, *hitem = NULL;
16276         proto_tree *tree = NULL, *htree = NULL;
16277         guint8          flags;
16278         guint16         flags2;
16279         static smb_info_t       si_arr[20];
16280         static int si_counter=0;
16281         smb_info_t              *si;
16282         smb_saved_info_t *sip = NULL;
16283         smb_saved_info_key_t key;
16284         smb_saved_info_key_t *new_key;
16285         guint32 nt_status = 0;
16286         guint8 errclass = 0;
16287         guint16 errcode = 0;
16288         guint32 pid_mid;
16289         conversation_t *conversation;
16290         nstime_t ns;
16291
16292         si_counter++;
16293         if(si_counter==20){
16294                 si_counter=0;
16295         }
16296         si=&si_arr[si_counter];
16297
16298         top_tree=parent_tree;
16299
16300         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
16301                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
16302         }
16303         if (check_col(pinfo->cinfo, COL_INFO)){
16304                 col_clear(pinfo->cinfo, COL_INFO);
16305         }
16306
16307         /* start off using the local variable, we will allocate a new one if we
16308            need to*/
16309         si->cmd = tvb_get_guint8(tvb, offset+4);
16310         flags = tvb_get_guint8(tvb, offset+9);
16311         /*
16312          * XXX - in some SMB-over-OSI-transport and SMB-over-Vines traffic,
16313          * the direction flag appears never to be set, even for what appear
16314          * to be replies.  Do some SMB servers fail to set that flag,
16315          * under the assumption that the client knows it's a reply because
16316          * it received it?
16317          */
16318         si->request = !(flags&SMB_FLAGS_DIRN);
16319         flags2 = tvb_get_letohs(tvb, offset+10);
16320         if(flags2 & 0x8000){
16321                 si->unicode = TRUE; /* Mark them as Unicode */
16322         } else {
16323                 si->unicode = FALSE;
16324         }
16325         si->tid = tvb_get_letohs(tvb, offset+24);
16326         si->pid = tvb_get_letohs(tvb, offset+26);
16327         si->uid = tvb_get_letohs(tvb, offset+28);
16328         si->mid = tvb_get_letohs(tvb, offset+30);
16329         pid_mid = (si->pid << 16) | si->mid;
16330         si->info_level = -1;
16331         si->info_count = -1;
16332
16333         if (parent_tree) {
16334                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
16335                         -1, FALSE);
16336                 tree = proto_item_add_subtree(item, ett_smb);
16337
16338                 hitem = proto_tree_add_text(tree, tvb, offset, 32,
16339                         "SMB Header");
16340
16341                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
16342         }
16343
16344         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
16345         offset += 4;  /* Skip the marker */
16346
16347         /* find which conversation we are part of and get the tables for that
16348            conversation*/
16349         conversation = find_conversation(&pinfo->src, &pinfo->dst,
16350                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
16351         if(!conversation){
16352                 /* OK this is a new conversation so lets create it */
16353                 conversation = conversation_new(&pinfo->src, &pinfo->dst,
16354                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
16355         }
16356         /* see if we already have the smb data for this conversation */
16357         si->ct=conversation_get_proto_data(conversation, proto_smb);
16358         if(!si->ct){
16359                 /* No, not yet. create it and attach it to the conversation */
16360                 si->ct = g_mem_chunk_alloc(conv_tables_chunk);
16361                 conv_tables = g_slist_prepend(conv_tables, si->ct);
16362                 si->ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
16363                         smb_saved_info_equal_matched);
16364                 si->ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
16365                         smb_saved_info_equal_unmatched);
16366                 si->ct->tid_service=g_hash_table_new(
16367                         smb_saved_info_hash_unmatched,
16368                         smb_saved_info_equal_unmatched);
16369                 conversation_add_proto_data(conversation, proto_smb, si->ct);
16370         }
16371
16372         if( (si->request)
16373             &&  (si->mid==0)
16374             &&  (si->uid==0)
16375             &&  (si->pid==0)
16376             &&  (si->tid==0) ){
16377                 /* this is a broadcast SMB packet, there will not be a reply.
16378                    We dont need to do anything
16379                 */
16380                 si->unidir = TRUE;
16381         } else if( (si->cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
16382                    ||(si->cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
16383                    ||(si->cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
16384                    ||(si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
16385                 /* Ok, we got a special request type. This request is either
16386                    an NT Cancel or a continuation relative to a real request
16387                    in an earlier packet.  In either case, we don't expect any
16388                    responses to this packet.  For continuations, any later
16389                    responses we see really just belong to the original request.
16390                    Anyway, we want to remember this packet somehow and
16391                    remember which original request it is associated with so
16392                    we can say nice things such as "This is a Cancellation to
16393                    the request in frame x", but we don't want the
16394                    request/response matching to get messed up.
16395
16396                    The only thing we do in this case is trying to find which original
16397                    request we match with and insert an entry for this "special"
16398                    request for later reference. We continue to reference the original
16399                    requests smb_saved_info_t but we dont touch it or change anything
16400                    in it.
16401                 */
16402
16403                 si->unidir = TRUE;  /*we dont expect an answer to this one*/
16404
16405                 if(!pinfo->fd->flags.visited){
16406                         /* try to find which original call we match and if we
16407                            find it add us to the matched table. Dont touch
16408                            anything else since we dont want this one to mess
16409                            up the request/response matching. We still consider
16410                            the initial call the real request and this is only
16411                            some sort of continuation.
16412                         */
16413                         /* we only check the unmatched table and assume that the
16414                            last seen MID matching ours is the right one.
16415                            This can fail but is better than nothing
16416                         */
16417                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
16418                         if(sip!=NULL){
16419                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16420                                 new_key->frame = pinfo->fd->num;
16421                                 new_key->pid_mid = pid_mid;
16422                                 g_hash_table_insert(si->ct->matched, new_key,
16423                                     sip);
16424                         }
16425                 } else {
16426                         /* we have seen this packet before; check the
16427                            matching table
16428                         */
16429                         key.frame = pinfo->fd->num;
16430                         key.pid_mid = pid_mid;
16431                         sip=g_hash_table_lookup(si->ct->matched, &key);
16432                         if(sip==NULL){
16433                         /*
16434                           We didn't find it.
16435                           Too bad, unfortunately there is not really much we can
16436                           do now since this means that we never saw the initial
16437                           request.
16438                          */
16439                         }
16440                 }
16441
16442
16443                 if(sip && sip->frame_req){
16444                         switch(si->cmd){
16445                         case SMB_COM_NT_CANCEL:
16446                                 proto_tree_add_uint(htree, hf_smb_cancel_to,
16447                                                     tvb, 0, 0, sip->frame_req);
16448                                 break;
16449                         case SMB_COM_TRANSACTION_SECONDARY:
16450                         case SMB_COM_TRANSACTION2_SECONDARY:
16451                         case SMB_COM_NT_TRANSACT_SECONDARY:
16452                                 proto_tree_add_uint(htree, hf_smb_continuation_to,
16453                                                     tvb, 0, 0, sip->frame_req);
16454                                 break;
16455                         }
16456                 } else {
16457                         switch(si->cmd){
16458                         case SMB_COM_NT_CANCEL:
16459                                 proto_tree_add_text(htree, tvb, 0, 0,
16460                                                     "Cancellation to: <unknown frame>");
16461                                 break;
16462                         case SMB_COM_TRANSACTION_SECONDARY:
16463                         case SMB_COM_TRANSACTION2_SECONDARY:
16464                         case SMB_COM_NT_TRANSACT_SECONDARY:
16465                                 proto_tree_add_text(htree, tvb, 0, 0,
16466                                                     "Continuation to: <unknown frame>");
16467                                 break;
16468                         }
16469                 }
16470         } else { /* normal bidirectional request or response */
16471                 si->unidir = FALSE;
16472
16473                 if(!pinfo->fd->flags.visited){
16474                         /* first see if we find an unmatched smb "equal" to
16475                            the current one
16476                         */
16477                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
16478                         if(sip!=NULL){
16479                                 gboolean cmd_match=FALSE;
16480
16481                                 /*
16482                                  * Make sure the SMB we found was the
16483                                  * same command, or a different command
16484                                  * that's another valid type of reply
16485                                  * to that command.
16486                                  */
16487                                 if(si->cmd==sip->cmd){
16488                                         cmd_match=TRUE;
16489                                 }
16490                                 else if(si->cmd==SMB_COM_NT_CANCEL){
16491                                         cmd_match=TRUE;
16492                                 }
16493                                 else if((si->cmd==SMB_COM_TRANSACTION_SECONDARY)
16494                                      && (sip->cmd==SMB_COM_TRANSACTION)){
16495                                         cmd_match=TRUE;
16496                                 }
16497                                 else if((si->cmd==SMB_COM_TRANSACTION2_SECONDARY)
16498                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
16499                                         cmd_match=TRUE;
16500                                 }
16501                                 else if((si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)
16502                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
16503                                         cmd_match=TRUE;
16504                                 }
16505
16506                                 if( (si->request) || (!cmd_match) ) {
16507                                         /* If we are processing an SMB request but there was already
16508                                            another "identical" smb resuest we had not matched yet.
16509                                            This must mean that either we have a retransmission or that the
16510                                            response to the previous one was lost and the client has reused
16511                                            the MID for this conversation. In either case it's not much more
16512                                            we can do than forget the old request and concentrate on the
16513                                            present one instead.
16514
16515                                            We also do this cleanup if we see that the cmd in the original
16516                                            request in sip->cmd is not compatible with the current cmd.
16517                                            This is to prevent matching errors such as if there were two
16518                                            SMBs of different cmds but with identical MID and PID values and
16519                                            if ethereal lost the first reply and the second request.
16520                                         */
16521                                         g_hash_table_remove(si->ct->unmatched, (void *)pid_mid);
16522                                         sip=NULL; /* XXX should free it as well */
16523                                 } else {
16524                                         /* we have found a response to some request we have seen earlier.
16525                                            What we do now depends on whether this is the first response
16526                                            to that request we see (id frame_res==0) or not.
16527                                         */
16528                                         if(sip->frame_res==0){
16529                                                 /* ok it is the first response we have seen to this packet */
16530                                                 sip->frame_res = pinfo->fd->num;
16531                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16532                                                 new_key->frame = sip->frame_res;
16533                                                 new_key->pid_mid = pid_mid;
16534                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16535                                         } else {
16536                                                 /* We have already seen another response to this MID.
16537                                                    Since the MID in reality is only something like 10 bits
16538                                                    this probably means that we just have a MID that is being
16539                                                    reused due to the small MID space and that this is a new
16540                                                    command we did not see the original request for.
16541                                                 */
16542                                                 sip=NULL;
16543                                         }
16544                                 }
16545                         }
16546                         if(si->request){
16547                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
16548                                 sip->frame_req = pinfo->fd->num;
16549                                 sip->frame_res = 0;
16550                                 sip->req_time.secs=pinfo->fd->abs_secs;
16551                                 sip->req_time.nsecs=pinfo->fd->abs_usecs*1000;
16552                                 sip->flags = 0;
16553                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)
16554                                     == (void *)TID_IPC) {
16555                                         sip->flags |= SMB_SIF_TID_IS_IPC;
16556                                 }
16557                                 sip->cmd = si->cmd;
16558                                 sip->extra_info = NULL;
16559                                 g_hash_table_insert(si->ct->unmatched, (void *)pid_mid, sip);
16560                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16561                                 new_key->frame = sip->frame_req;
16562                                 new_key->pid_mid = pid_mid;
16563                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16564                         }
16565                 } else {
16566                         /* we have seen this packet before; check the
16567                            matching table.
16568                            If we haven't yet seen the reply, we won't
16569                            find the info for it; we don't need it, as
16570                            we only use it to save information, and, as
16571                            we've seen this packet before, we've already
16572                            saved the information.
16573                         */
16574                         key.frame = pinfo->fd->num;
16575                         key.pid_mid = pid_mid;
16576                         sip=g_hash_table_lookup(si->ct->matched, &key);
16577                 }
16578         }
16579
16580         /*
16581          * Pass the "sip" on to subdissectors through "si".
16582          */
16583         si->sip = sip;
16584
16585         if (sip != NULL) {
16586                 /*
16587                  * Put in fields for the frame number of the frame to which
16588                  * this is a response or the frame with the response to this
16589                  * frame - if we know the frame number (i.e., it's not 0).
16590                  */
16591                 if(si->request){
16592                         if (sip->frame_res != 0)
16593                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
16594                 } else {
16595                         if (sip->frame_req != 0) {
16596                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
16597                                 ns.secs = pinfo->fd->abs_secs - sip->req_time.secs;
16598                                 ns.nsecs = pinfo->fd->abs_usecs*1000 - sip->req_time.nsecs;
16599                                 if(ns.nsecs<0){
16600                                         ns.nsecs+=1000000000;
16601                                         ns.secs--;
16602                                 }
16603                                 proto_tree_add_time(htree, hf_smb_time, tvb,
16604                                     0, 0, &ns);
16605                         }
16606                 }
16607         }
16608
16609         /* smb command */
16610         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);
16611         offset += 1;
16612
16613         if(flags2 & 0x4000){
16614                 /* handle NT 32 bit error code */
16615
16616                 nt_status = tvb_get_letohl(tvb, offset);
16617
16618                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
16619                         TRUE);
16620                 offset += 4;
16621
16622         } else {
16623                 /* handle DOS error code & class */
16624                 errclass = tvb_get_guint8(tvb, offset);
16625                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
16626                         errclass);
16627                 offset += 1;
16628
16629                 /* reserved byte */
16630                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
16631                 offset += 1;
16632
16633                 /* error code */
16634                 /* XXX - the type of this field depends on the value of
16635                  * "errcls", so there is isn't a single value_string array
16636                  * fo it, so there can't be a single field for it.
16637                  */
16638                 errcode = tvb_get_letohs(tvb, offset);
16639                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
16640                         offset, 2, errcode, "Error Code: %s",
16641                         decode_smb_error(errclass, errcode));
16642                 offset += 2;
16643         }
16644
16645         /* flags */
16646         offset = dissect_smb_flags(tvb, htree, offset);
16647
16648         /* flags2 */
16649         offset = dissect_smb_flags2(tvb, htree, offset);
16650
16651         /*
16652          * The document at
16653          *
16654          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
16655          *
16656          * (a text version of "Microsoft Networks SMB FILE SHARING
16657          * PROTOCOL, Document Version 6.0p") says that:
16658          *
16659          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
16660          *      the "High Part of PID";
16661          *
16662          *      the next four bytes are reserved;
16663          *
16664          *      the next four bytes are, for SMB-over-IPX (with no
16665          *      NetBIOS involved) two bytes of Session ID and two bytes
16666          *      of SequenceNumber.
16667          *
16668          * Network Monitor 2.x dissects the four bytes before the Session ID
16669          * as a "Key", and the two bytes after the SequenceNumber as
16670          * a "Group ID".
16671          *
16672          * The "High Part of PID" has been seen in calls other than NT
16673          * Create and X, although most of them appear to be I/O on DCE RPC
16674          * pipes opened with the NT Create and X in question.
16675          */
16676         proto_tree_add_item(htree, hf_smb_pid_high, tvb, offset, 2, TRUE);
16677         offset += 2;
16678
16679         if (pinfo->ptype == PT_IPX &&
16680             (pinfo->match_port == IPX_SOCKET_NWLINK_SMB_SERVER ||
16681              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_REDIR ||
16682              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_MESSENGER)) {
16683                 /*
16684                  * This is SMB-over-IPX.
16685                  * XXX - do we have to worry about "sequenced commands",
16686                  * as per the Samba document?  They say that for
16687                  * "unsequenced commands" (with a sequence number of 0),
16688                  * the Mid must be unique, but perhaps the Mid doesn't
16689                  * have to be unique for sequenced commands.  In at least
16690                  * one capture with SMB-over-IPX, however, the Mids
16691                  * are unique even for sequenced commands.
16692                  */
16693                 /* Key */
16694                 proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
16695                     TRUE);
16696                 offset += 4;
16697
16698                 /* Session ID */
16699                 proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
16700                     TRUE);
16701                 offset += 2;
16702
16703                 /* Sequence number */
16704                 proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
16705                     TRUE);
16706                 offset += 2;
16707
16708                 /* Group ID */
16709                 proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
16710                     TRUE);
16711                 offset += 2;
16712         } else {
16713                 /*
16714                  * According to http://ubiqx.org/cifs/SMB.html#SMB.4.2.1
16715                  * and http://ubiqx.org/cifs/SMB.html#SMB.5.5.1 the 8
16716                  * bytes after the "High part of PID" are an 8-byte
16717                  * signature ...
16718                  */
16719                 proto_tree_add_item(htree, hf_smb_sig, tvb, offset, 8, TRUE);
16720                 offset += 8;
16721
16722                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2, TRUE);
16723                 offset += 2;
16724         }
16725
16726         /* TID */
16727         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si->tid);
16728         offset += 2;
16729
16730         /* PID */
16731         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
16732         offset += 2;
16733
16734         /* UID */
16735         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si->uid);
16736         offset += 2;
16737
16738         /* MID */
16739         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
16740         offset += 2;
16741
16742         pinfo->private_data = si;
16743
16744         /* tap the packet before the dissectors are called so we still get
16745            the tap listener called even if there is an exception.
16746         */
16747         tap_queue_packet(smb_tap, pinfo, si);
16748         dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE);
16749
16750         /* Append error info from this packet to info string. */
16751         if (!si->request && check_col(pinfo->cinfo, COL_INFO)) {
16752                 if (flags2 & 0x4000) {
16753                         /*
16754                          * The status is an NT status code; was there
16755                          * an error?
16756                          */
16757                         if ((nt_status & 0xC0000000) == 0xC0000000) {
16758                                 /*
16759                                  * Yes.
16760                                  */
16761                                 col_append_fstr(
16762                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16763                                         val_to_str(nt_status, NT_errors,
16764                                             "Unknown (0x%08X)"));
16765                         }
16766                 } else {
16767                         /*
16768                          * The status is a DOS error class and code; was
16769                          * there an error?
16770                          */
16771                         if (errclass != SMB_SUCCESS) {
16772                                 /*
16773                                  * Yes.
16774                                  */
16775                                 col_append_fstr(
16776                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16777                                         decode_smb_error(errclass, errcode));
16778                         }
16779                 }
16780         }
16781 }
16782
16783 static gboolean
16784 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16785 {
16786         /* must check that this really is a smb packet */
16787         if (!tvb_bytes_exist(tvb, 0, 4))
16788                 return FALSE;
16789
16790         if( (tvb_get_guint8(tvb, 0) != 0xff)
16791             || (tvb_get_guint8(tvb, 1) != 'S')
16792             || (tvb_get_guint8(tvb, 2) != 'M')
16793             || (tvb_get_guint8(tvb, 3) != 'B') ){
16794                 return FALSE;
16795         }
16796
16797         dissect_smb(tvb, pinfo, parent_tree);
16798         return TRUE;
16799 }
16800
16801 void
16802 proto_register_smb(void)
16803 {
16804         static hf_register_info hf[] = {
16805         { &hf_smb_cmd,
16806                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
16807                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
16808
16809         { &hf_smb_word_count,
16810                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
16811                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
16812
16813         { &hf_smb_byte_count,
16814                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
16815                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
16816
16817         { &hf_smb_response_to,
16818                 { "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
16819                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
16820
16821         { &hf_smb_time,
16822                 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
16823                 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
16824
16825         { &hf_smb_response_in,
16826                 { "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
16827                 NULL, 0, "The response to this packet is in this packet", HFILL }},
16828
16829         { &hf_smb_continuation_to,
16830                 { "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
16831                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
16832
16833         { &hf_smb_nt_status,
16834                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
16835                 VALS(NT_errors), 0, "NT Status code", HFILL }},
16836
16837         { &hf_smb_error_class,
16838                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
16839                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
16840
16841         { &hf_smb_error_code,
16842                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
16843                 NULL, 0, "DOS Error Code", HFILL }},
16844
16845         { &hf_smb_reserved,
16846                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
16847                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
16848
16849         { &hf_smb_sig,
16850                 { "Signature", "smb.signature", FT_BYTES, BASE_HEX,
16851                 NULL, 0, "Signature bytes", HFILL }},
16852
16853         { &hf_smb_key,
16854                 { "Key", "smb.key", FT_UINT32, BASE_HEX,
16855                 NULL, 0, "SMB-over-IPX Key", HFILL }},
16856
16857         { &hf_smb_session_id,
16858                 { "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
16859                 NULL, 0, "SMB-over-IPX Session ID", HFILL }},
16860
16861         { &hf_smb_sequence_num,
16862                 { "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
16863                 NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
16864
16865         { &hf_smb_group_id,
16866                 { "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
16867                 NULL, 0, "SMB-over-IPX Group ID", HFILL }},
16868
16869         { &hf_smb_pid,
16870                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
16871                 NULL, 0, "Process ID", HFILL }},
16872
16873         { &hf_smb_pid_high,
16874                 { "Process ID High", "smb.pid.high", FT_UINT16, BASE_DEC,
16875                 NULL, 0, "Process ID High Bytes", HFILL }},
16876
16877         { &hf_smb_tid,
16878                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
16879                 NULL, 0, "Tree ID", HFILL }},
16880
16881         { &hf_smb_uid,
16882                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
16883                 NULL, 0, "User ID", HFILL }},
16884
16885         { &hf_smb_mid,
16886                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
16887                 NULL, 0, "Multiplex ID", HFILL }},
16888
16889         { &hf_smb_flags_lock,
16890                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
16891                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
16892
16893         { &hf_smb_flags_receive_buffer,
16894                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
16895                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
16896
16897         { &hf_smb_flags_caseless,
16898                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
16899                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
16900
16901         { &hf_smb_flags_canon,
16902                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
16903                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
16904
16905         { &hf_smb_flags_oplock,
16906                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
16907                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
16908
16909         { &hf_smb_flags_notify,
16910                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
16911                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
16912
16913         { &hf_smb_flags_response,
16914                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
16915                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
16916
16917         { &hf_smb_flags2_long_names_allowed,
16918                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
16919                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
16920
16921         { &hf_smb_flags2_ea,
16922                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
16923                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
16924
16925         { &hf_smb_flags2_sec_sig,
16926                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
16927                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
16928
16929         { &hf_smb_flags2_long_names_used,
16930                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
16931                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
16932
16933         { &hf_smb_flags2_esn,
16934                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
16935                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
16936
16937         { &hf_smb_flags2_dfs,
16938                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
16939                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
16940
16941         { &hf_smb_flags2_roe,
16942                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
16943                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
16944
16945         { &hf_smb_flags2_nt_error,
16946                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
16947                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
16948
16949         { &hf_smb_flags2_string,
16950                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
16951                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
16952
16953         { &hf_smb_buffer_format,
16954                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
16955                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
16956
16957         { &hf_smb_dialect_name,
16958                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
16959                 NULL, 0, "Name of dialect", HFILL }},
16960
16961         { &hf_smb_dialect_index,
16962                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
16963                 NULL, 0, "Index of selected dialect", HFILL }},
16964
16965         { &hf_smb_max_trans_buf_size,
16966                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
16967                 NULL, 0, "Maximum transmit buffer size", HFILL }},
16968
16969         { &hf_smb_max_mpx_count,
16970                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
16971                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
16972
16973         { &hf_smb_max_vcs_num,
16974                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
16975                 NULL, 0, "Maximum VCs between client and server", HFILL }},
16976
16977         { &hf_smb_session_key,
16978                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
16979                 NULL, 0, "Unique token identifying this session", HFILL }},
16980
16981         { &hf_smb_server_timezone,
16982                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
16983                 NULL, 0, "Current timezone at server.", HFILL }},
16984
16985         { &hf_smb_encryption_key_length,
16986                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
16987                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
16988
16989         { &hf_smb_encryption_key,
16990                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
16991                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
16992
16993         { &hf_smb_primary_domain,
16994                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
16995                 NULL, 0, "The server's primary domain", HFILL }},
16996
16997         { &hf_smb_server,
16998                 { "Server", "smb.server", FT_STRING, BASE_NONE,
16999                 NULL, 0, "The name of the DC/server", HFILL }},
17000
17001         { &hf_smb_max_raw_buf_size,
17002                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
17003                 NULL, 0, "Maximum raw buffer size", HFILL }},
17004
17005         { &hf_smb_server_guid,
17006                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
17007                 NULL, 0, "Globally unique identifier for this server", HFILL }},
17008
17009         { &hf_smb_security_blob_len,
17010                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
17011                 NULL, 0, "Security blob length", HFILL }},
17012
17013         { &hf_smb_security_blob,
17014                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
17015                 NULL, 0, "Security blob", HFILL }},
17016
17017         { &hf_smb_sm_mode16,
17018                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
17019                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
17020
17021         { &hf_smb_sm_password16,
17022                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
17023                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
17024
17025         { &hf_smb_sm_mode,
17026                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
17027                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
17028
17029         { &hf_smb_sm_password,
17030                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
17031                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
17032
17033         { &hf_smb_sm_signatures,
17034                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
17035                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
17036
17037         { &hf_smb_sm_sig_required,
17038                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
17039                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
17040
17041         { &hf_smb_rm_read,
17042                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
17043                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
17044
17045         { &hf_smb_rm_write,
17046                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
17047                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
17048
17049         { &hf_smb_server_date_time,
17050                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
17051                 NULL, 0, "Current date and time at server", HFILL }},
17052
17053         { &hf_smb_server_smb_date,
17054                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
17055                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
17056
17057         { &hf_smb_server_smb_time,
17058                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
17059                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
17060
17061         { &hf_smb_server_cap_raw_mode,
17062                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
17063                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
17064
17065         { &hf_smb_server_cap_mpx_mode,
17066                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
17067                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
17068
17069         { &hf_smb_server_cap_unicode,
17070                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
17071                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
17072
17073         { &hf_smb_server_cap_large_files,
17074                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
17075                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
17076
17077         { &hf_smb_server_cap_nt_smbs,
17078                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
17079                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
17080
17081         { &hf_smb_server_cap_rpc_remote_apis,
17082                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
17083                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
17084
17085         { &hf_smb_server_cap_nt_status,
17086                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
17087                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
17088
17089         { &hf_smb_server_cap_level_ii_oplocks,
17090                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
17091                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
17092
17093         { &hf_smb_server_cap_lock_and_read,
17094                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
17095                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
17096
17097         { &hf_smb_server_cap_nt_find,
17098                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
17099                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
17100
17101         { &hf_smb_server_cap_dfs,
17102                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
17103                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
17104
17105         { &hf_smb_server_cap_infolevel_passthru,
17106                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
17107                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
17108
17109         { &hf_smb_server_cap_large_readx,
17110                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
17111                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
17112
17113         { &hf_smb_server_cap_large_writex,
17114                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
17115                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
17116
17117         { &hf_smb_server_cap_unix,
17118                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
17119                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
17120
17121         { &hf_smb_server_cap_reserved,
17122                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
17123                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
17124
17125         { &hf_smb_server_cap_bulk_transfer,
17126                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
17127                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
17128
17129         { &hf_smb_server_cap_compressed_data,
17130                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
17131                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
17132
17133         { &hf_smb_server_cap_extended_security,
17134                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
17135                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
17136
17137         { &hf_smb_system_time,
17138                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
17139                 NULL, 0, "System Time", HFILL }},
17140
17141         { &hf_smb_unknown,
17142                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
17143                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
17144
17145         { &hf_smb_dir_name,
17146                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
17147                 NULL, 0, "SMB Directory Name", HFILL }},
17148
17149         { &hf_smb_echo_count,
17150                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
17151                 NULL, 0, "Number of times to echo data back", HFILL }},
17152
17153         { &hf_smb_echo_data,
17154                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
17155                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
17156
17157         { &hf_smb_echo_seq_num,
17158                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
17159                 NULL, 0, "Sequence number for this echo response", HFILL }},
17160
17161         { &hf_smb_max_buf_size,
17162                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
17163                 NULL, 0, "Max client buffer size", HFILL }},
17164
17165         { &hf_smb_path,
17166                 { "Path", "smb.path", FT_STRING, BASE_NONE,
17167                 NULL, 0, "Path. Server name and share name", HFILL }},
17168
17169         { &hf_smb_service,
17170                 { "Service", "smb.service", FT_STRING, BASE_NONE,
17171                 NULL, 0, "Service name", HFILL }},
17172
17173         { &hf_smb_password,
17174                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
17175                 NULL, 0, "Password", HFILL }},
17176
17177         { &hf_smb_ansi_password,
17178                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
17179                 NULL, 0, "ANSI Password", HFILL }},
17180
17181         { &hf_smb_unicode_password,
17182                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
17183                 NULL, 0, "Unicode Password", HFILL }},
17184
17185         { &hf_smb_move_flags_file,
17186                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
17187                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17188
17189         { &hf_smb_move_flags_dir,
17190                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
17191                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17192
17193         { &hf_smb_move_flags_verify,
17194                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
17195                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17196
17197         { &hf_smb_files_moved,
17198                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
17199                 NULL, 0, "Number of files moved", HFILL }},
17200
17201         { &hf_smb_copy_flags_file,
17202                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
17203                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17204
17205         { &hf_smb_copy_flags_dir,
17206                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
17207                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17208
17209         { &hf_smb_copy_flags_dest_mode,
17210                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
17211                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
17212
17213         { &hf_smb_copy_flags_source_mode,
17214                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
17215                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
17216
17217         { &hf_smb_copy_flags_verify,
17218                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
17219                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17220
17221         { &hf_smb_copy_flags_tree_copy,
17222                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
17223                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
17224
17225         { &hf_smb_copy_flags_ea_action,
17226                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
17227                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
17228
17229         { &hf_smb_count,
17230                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
17231                 NULL, 0, "Count number of items/bytes", HFILL }},
17232
17233         { &hf_smb_count_low,
17234                 { "Count Low", "smb.count_low", FT_UINT16, BASE_DEC,
17235                 NULL, 0, "Count number of items/bytes, Low 16 bits", HFILL }},
17236
17237         { &hf_smb_count_high,
17238                 { "Count High (multiply with 64K)", "smb.count_high", FT_UINT16, BASE_DEC,
17239                 NULL, 0, "Count number of items/bytes, High 16 bits", HFILL }},
17240
17241         { &hf_smb_file_name,
17242                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
17243                 NULL, 0, "File Name", HFILL }},
17244
17245         { &hf_smb_open_function_create,
17246                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
17247                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
17248
17249         { &hf_smb_open_function_open,
17250                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
17251                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
17252
17253         { &hf_smb_fid,
17254                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
17255                 NULL, 0, "FID: File ID", HFILL }},
17256
17257         { &hf_smb_file_attr_read_only_16bit,
17258                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
17259                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17260
17261         { &hf_smb_file_attr_read_only_8bit,
17262                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
17263                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17264
17265         { &hf_smb_file_attr_hidden_16bit,
17266                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
17267                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17268
17269         { &hf_smb_file_attr_hidden_8bit,
17270                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
17271                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17272
17273         { &hf_smb_file_attr_system_16bit,
17274                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
17275                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17276
17277         { &hf_smb_file_attr_system_8bit,
17278                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
17279                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17280
17281         { &hf_smb_file_attr_volume_16bit,
17282                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
17283                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
17284
17285         { &hf_smb_file_attr_volume_8bit,
17286                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
17287                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
17288
17289         { &hf_smb_file_attr_directory_16bit,
17290                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
17291                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17292
17293         { &hf_smb_file_attr_directory_8bit,
17294                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
17295                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17296
17297         { &hf_smb_file_attr_archive_16bit,
17298                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
17299                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17300
17301         { &hf_smb_file_attr_archive_8bit,
17302                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
17303                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17304
17305         { &hf_smb_file_attr_device,
17306                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
17307                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
17308
17309         { &hf_smb_file_attr_normal,
17310                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
17311                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
17312
17313         { &hf_smb_file_attr_temporary,
17314                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
17315                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
17316
17317         { &hf_smb_file_attr_sparse,
17318                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
17319                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
17320
17321         { &hf_smb_file_attr_reparse,
17322                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
17323                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
17324
17325         { &hf_smb_file_attr_compressed,
17326                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
17327                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
17328
17329         { &hf_smb_file_attr_offline,
17330                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
17331                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
17332
17333         { &hf_smb_file_attr_not_content_indexed,
17334                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
17335                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
17336
17337         { &hf_smb_file_attr_encrypted,
17338                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
17339                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
17340
17341         { &hf_smb_file_size,
17342                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
17343                 NULL, 0, "File Size", HFILL }},
17344
17345         { &hf_smb_search_attribute_read_only,
17346                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
17347                 TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
17348
17349         { &hf_smb_search_attribute_hidden,
17350                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
17351                 TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
17352
17353         { &hf_smb_search_attribute_system,
17354                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
17355                 TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
17356
17357         { &hf_smb_search_attribute_volume,
17358                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
17359                 TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
17360
17361         { &hf_smb_search_attribute_directory,
17362                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
17363                 TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
17364
17365         { &hf_smb_search_attribute_archive,
17366                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
17367                 TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
17368
17369         { &hf_smb_access_mode,
17370                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
17371                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
17372
17373         { &hf_smb_access_sharing,
17374                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
17375                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
17376
17377         { &hf_smb_access_locality,
17378                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
17379                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
17380
17381         { &hf_smb_access_caching,
17382                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
17383                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
17384
17385         { &hf_smb_access_writetru,
17386                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
17387                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
17388
17389         { &hf_smb_create_time,
17390                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
17391                 NULL, 0, "Creation Time", HFILL }},
17392
17393         { &hf_smb_modify_time,
17394                 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
17395                   NULL, 0, "Modification Time", HFILL }},
17396
17397         { &hf_smb_backup_time,
17398                 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
17399                   NULL, 0, "Backup time", HFILL}},
17400
17401         { &hf_smb_mac_alloc_block_count,
17402                 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
17403                   NULL, 0, "Allocation Block Count", HFILL}},
17404
17405         { &hf_smb_mac_alloc_block_size,
17406                 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
17407                   NULL, 0, "Allocation Block Size", HFILL}},
17408
17409         { &hf_smb_mac_free_block_count,
17410                 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
17411                   NULL, 0, "Free Block Count", HFILL}},
17412
17413         { &hf_smb_mac_root_file_count,
17414                 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
17415                 NULL, 0, "Root File Count", HFILL}},
17416
17417         { &hf_smb_mac_root_dir_count,
17418           { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
17419             NULL, 0, "Root Directory Count", HFILL}},
17420
17421         { &hf_smb_mac_file_count,
17422           { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
17423             NULL, 0, "File Count", HFILL}},
17424
17425         { &hf_smb_mac_dir_count,
17426           { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
17427             NULL, 0, "Directory Count", HFILL}},
17428
17429         { &hf_smb_mac_support_flags,
17430           { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
17431             NULL, 0, "Mac Support Flags", HFILL}},
17432
17433         { &hf_smb_mac_sup_access_ctrl,
17434           { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
17435             TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
17436
17437         { &hf_smb_mac_sup_getset_comments,
17438           { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
17439             TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
17440
17441         { &hf_smb_mac_sup_desktopdb_calls,
17442           { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
17443             TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
17444
17445         { &hf_smb_mac_sup_unique_ids,
17446           { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
17447             TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
17448
17449         { &hf_smb_mac_sup_streams,
17450           { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
17451             TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
17452
17453         { &hf_smb_create_dos_date,
17454                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
17455                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
17456
17457         { &hf_smb_create_dos_time,
17458                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
17459                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
17460
17461         { &hf_smb_last_write_time,
17462                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
17463                 NULL, 0, "Time this file was last written to", HFILL }},
17464
17465         { &hf_smb_last_write_dos_date,
17466                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
17467                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
17468
17469         { &hf_smb_last_write_dos_time,
17470                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
17471                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
17472
17473         { &hf_smb_old_file_name,
17474                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
17475                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
17476
17477         { &hf_smb_offset,
17478                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
17479                 NULL, 0, "Offset in file", HFILL }},
17480
17481         { &hf_smb_remaining,
17482                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
17483                 NULL, 0, "Remaining number of bytes", HFILL }},
17484
17485         { &hf_smb_padding,
17486                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
17487                 NULL, 0, "Padding or unknown data", HFILL }},
17488
17489         { &hf_smb_file_data,
17490                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
17491                 NULL, 0, "Data read/written to the file", HFILL }},
17492
17493         { &hf_smb_mac_fndrinfo,
17494                 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_HEX,
17495                   NULL, 0, "Finder Info", HFILL}},
17496
17497         { &hf_smb_total_data_len,
17498                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
17499                 NULL, 0, "Total length of data", HFILL }},
17500
17501         { &hf_smb_data_len,
17502                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
17503                 NULL, 0, "Length of data", HFILL }},
17504
17505         { &hf_smb_data_len_low,
17506                 { "Data Length Low", "smb.data_len_low", FT_UINT16, BASE_DEC,
17507                 NULL, 0, "Length of data, Low 16 bits", HFILL }},
17508
17509         { &hf_smb_data_len_high,
17510                 { "Data Length High (multiply with 64K)", "smb.data_len_high", FT_UINT16, BASE_DEC,
17511                 NULL, 0, "Length of data, High 16 bits", HFILL }},
17512
17513         { &hf_smb_seek_mode,
17514                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
17515                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
17516
17517         { &hf_smb_access_time,
17518                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
17519                 NULL, 0, "Last Access Time", HFILL }},
17520
17521         { &hf_smb_access_dos_date,
17522                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
17523                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
17524
17525         { &hf_smb_access_dos_time,
17526                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
17527                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
17528
17529         { &hf_smb_data_size,
17530                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
17531                 NULL, 0, "Data Size", HFILL }},
17532
17533         { &hf_smb_alloc_size,
17534                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
17535                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17536
17537         { &hf_smb_max_count,
17538                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
17539                 NULL, 0, "Maximum Count", HFILL }},
17540
17541         { &hf_smb_max_count_low,
17542                 { "Max Count Low", "smb.maxcount_low", FT_UINT16, BASE_DEC,
17543                 NULL, 0, "Maximum Count, Low 16 bits", HFILL }},
17544
17545         { &hf_smb_max_count_high,
17546                 { "Max Count High (multiply with 64K)", "smb.maxcount_high", FT_UINT16, BASE_DEC,
17547                 NULL, 0, "Maximum Count, High 16 bits", HFILL }},
17548
17549         { &hf_smb_min_count,
17550                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
17551                 NULL, 0, "Minimum Count", HFILL }},
17552
17553         { &hf_smb_timeout,
17554                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
17555                 NULL, 0, "Timeout in miliseconds", HFILL }},
17556
17557         { &hf_smb_high_offset,
17558                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
17559                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
17560
17561         { &hf_smb_units,
17562                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
17563                 NULL, 0, "Total number of units at server", HFILL }},
17564
17565         { &hf_smb_bpu,
17566                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
17567                 NULL, 0, "Blocks per unit at server", HFILL }},
17568
17569         { &hf_smb_blocksize,
17570                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
17571                 NULL, 0, "Block size (in bytes) at server", HFILL }},
17572
17573         { &hf_smb_freeunits,
17574                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
17575                 NULL, 0, "Number of free units at server", HFILL }},
17576
17577         { &hf_smb_data_offset,
17578                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17579                 NULL, 0, "Data Offset", HFILL }},
17580
17581         { &hf_smb_dcm,
17582                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
17583                 NULL, 0, "Data Compaction Mode", HFILL }},
17584
17585         { &hf_smb_request_mask,
17586                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
17587                 NULL, 0, "Connectionless mode mask", HFILL }},
17588
17589         { &hf_smb_response_mask,
17590                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
17591                 NULL, 0, "Connectionless mode mask", HFILL }},
17592
17593         { &hf_smb_search_id,
17594                 { "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
17595                 NULL, 0, "Search ID, handle for find operations", HFILL }},
17596
17597         { &hf_smb_write_mode_write_through,
17598                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
17599                 TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
17600
17601         { &hf_smb_write_mode_return_remaining,
17602                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
17603                 TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
17604
17605         { &hf_smb_write_mode_raw,
17606                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
17607                 TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
17608
17609         { &hf_smb_write_mode_message_start,
17610                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
17611                 TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
17612
17613         { &hf_smb_write_mode_connectionless,
17614                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
17615                 TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
17616
17617         { &hf_smb_resume_key_len,
17618                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
17619                 NULL, 0, "Resume Key length", HFILL }},
17620
17621         { &hf_smb_resume_find_id,
17622                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
17623                 NULL, 0, "Handle for Find operation", HFILL }},
17624
17625         { &hf_smb_resume_server_cookie,
17626                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
17627                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
17628
17629         { &hf_smb_resume_client_cookie,
17630                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
17631                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
17632
17633         { &hf_smb_andxoffset,
17634                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
17635                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
17636
17637         { &hf_smb_lock_type_large,
17638                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
17639                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
17640
17641         { &hf_smb_lock_type_cancel,
17642                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
17643                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
17644
17645         { &hf_smb_lock_type_change,
17646                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
17647                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
17648
17649         { &hf_smb_lock_type_oplock,
17650                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
17651                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
17652
17653         { &hf_smb_lock_type_shared,
17654                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
17655                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
17656
17657         { &hf_smb_locking_ol,
17658                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
17659                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
17660
17661         { &hf_smb_number_of_locks,
17662                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
17663                 NULL, 0, "Number of lock requests in this request", HFILL }},
17664
17665         { &hf_smb_number_of_unlocks,
17666                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
17667                 NULL, 0, "Number of unlock requests in this request", HFILL }},
17668
17669         { &hf_smb_lock_long_length,
17670                 { "Length", "smb.lock.length", FT_STRING, BASE_DEC,
17671                 NULL, 0, "Length of lock/unlock region", HFILL }},
17672
17673         { &hf_smb_lock_long_offset,
17674                 { "Offset", "smb.lock.offset", FT_STRING, BASE_DEC,
17675                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
17676
17677         { &hf_smb_file_type,
17678                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
17679                 VALS(filetype_vals), 0, "Type of file", HFILL }},
17680
17681         { &hf_smb_ipc_state_nonblocking,
17682                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
17683                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
17684
17685         { &hf_smb_ipc_state_endpoint,
17686                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
17687                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
17688
17689         { &hf_smb_ipc_state_pipe_type,
17690                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
17691                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
17692
17693         { &hf_smb_ipc_state_read_mode,
17694                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
17695                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
17696
17697         { &hf_smb_ipc_state_icount,
17698                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
17699                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
17700
17701         { &hf_smb_server_fid,
17702                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
17703                 NULL, 0, "Server unique File ID", HFILL }},
17704
17705         { &hf_smb_open_flags_add_info,
17706                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
17707                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
17708
17709         { &hf_smb_open_flags_ex_oplock,
17710                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
17711                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
17712
17713         { &hf_smb_open_flags_batch_oplock,
17714                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
17715                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
17716
17717         { &hf_smb_open_flags_ealen,
17718                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
17719                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
17720
17721         { &hf_smb_open_action_open,
17722                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
17723                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
17724
17725         { &hf_smb_open_action_lock,
17726                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
17727                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
17728
17729         { &hf_smb_vc_num,
17730                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
17731                 NULL, 0, "VC Number", HFILL }},
17732
17733         { &hf_smb_password_len,
17734                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
17735                 NULL, 0, "Length of password", HFILL }},
17736
17737         { &hf_smb_ansi_password_len,
17738                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
17739                 NULL, 0, "Length of ANSI password", HFILL }},
17740
17741         { &hf_smb_unicode_password_len,
17742                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
17743                 NULL, 0, "Length of Unicode password", HFILL }},
17744
17745         { &hf_smb_account,
17746                 { "Account", "smb.account", FT_STRING, BASE_NONE,
17747                 NULL, 0, "Account, username", HFILL }},
17748
17749         { &hf_smb_os,
17750                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
17751                 NULL, 0, "Which OS we are running", HFILL }},
17752
17753         { &hf_smb_lanman,
17754                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
17755                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
17756
17757         { &hf_smb_setup_action_guest,
17758                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
17759                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
17760
17761         { &hf_smb_fs,
17762                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
17763                 NULL, 0, "Native File System", HFILL }},
17764
17765         { &hf_smb_connect_flags_dtid,
17766                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
17767                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
17768
17769         { &hf_smb_connect_support_search,
17770                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
17771                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
17772
17773         { &hf_smb_connect_support_in_dfs,
17774                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
17775                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
17776
17777         { &hf_smb_max_setup_count,
17778                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
17779                 NULL, 0, "Maximum number of setup words to return", HFILL }},
17780
17781         { &hf_smb_total_param_count,
17782                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
17783                 NULL, 0, "Total number of parameter bytes", HFILL }},
17784
17785         { &hf_smb_total_data_count,
17786                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
17787                 NULL, 0, "Total number of data bytes", HFILL }},
17788
17789         { &hf_smb_max_param_count,
17790                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
17791                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
17792
17793         { &hf_smb_max_data_count,
17794                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
17795                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
17796
17797         { &hf_smb_param_disp16,
17798                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
17799                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17800
17801         { &hf_smb_param_count16,
17802                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
17803                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17804
17805         { &hf_smb_param_offset16,
17806                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
17807                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17808
17809         { &hf_smb_param_disp32,
17810                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
17811                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17812
17813         { &hf_smb_param_count32,
17814                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
17815                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17816
17817         { &hf_smb_param_offset32,
17818                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
17819                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17820
17821         { &hf_smb_data_count16,
17822                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
17823                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17824
17825         { &hf_smb_data_disp16,
17826                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
17827                 NULL, 0, "Data Displacement", HFILL }},
17828
17829         { &hf_smb_data_offset16,
17830                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17831                 NULL, 0, "Data Offset", HFILL }},
17832
17833         { &hf_smb_data_count32,
17834                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
17835                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17836
17837         { &hf_smb_data_disp32,
17838                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
17839                 NULL, 0, "Data Displacement", HFILL }},
17840
17841         { &hf_smb_data_offset32,
17842                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
17843                 NULL, 0, "Data Offset", HFILL }},
17844
17845         { &hf_smb_setup_count,
17846                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
17847                 NULL, 0, "Number of setup words in this buffer", HFILL }},
17848
17849         { &hf_smb_nt_trans_subcmd,
17850                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
17851                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
17852
17853         { &hf_smb_nt_ioctl_function_code,
17854                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
17855                 NULL, 0, "NT IOCTL function code", HFILL }},
17856
17857         { &hf_smb_nt_ioctl_isfsctl,
17858                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
17859                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
17860
17861         { &hf_smb_nt_ioctl_flags_root_handle,
17862                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
17863                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
17864
17865         { &hf_smb_nt_ioctl_data,
17866                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
17867                 NULL, 0, "Data for the IOCTL call", HFILL }},
17868
17869         { &hf_smb_nt_notify_action,
17870                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
17871                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
17872
17873         { &hf_smb_nt_notify_watch_tree,
17874                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
17875                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
17876
17877         { &hf_smb_nt_notify_stream_write,
17878                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
17879                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
17880
17881         { &hf_smb_nt_notify_stream_size,
17882                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
17883                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
17884
17885         { &hf_smb_nt_notify_stream_name,
17886                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
17887                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
17888
17889         { &hf_smb_nt_notify_security,
17890                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
17891                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
17892
17893         { &hf_smb_nt_notify_ea,
17894                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
17895                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
17896
17897         { &hf_smb_nt_notify_creation,
17898                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
17899                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
17900
17901         { &hf_smb_nt_notify_last_access,
17902                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
17903                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
17904
17905         { &hf_smb_nt_notify_last_write,
17906                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
17907                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
17908
17909         { &hf_smb_nt_notify_size,
17910                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
17911                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
17912
17913         { &hf_smb_nt_notify_attributes,
17914                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
17915                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
17916
17917         { &hf_smb_nt_notify_dir_name,
17918                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
17919                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
17920
17921         { &hf_smb_nt_notify_file_name,
17922                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
17923                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
17924
17925         { &hf_smb_root_dir_fid,
17926                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
17927                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
17928
17929         { &hf_smb_alloc_size64,
17930                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
17931                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17932
17933         { &hf_smb_nt_create_disposition,
17934                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
17935                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
17936
17937         { &hf_smb_sd_length,
17938                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
17939                 NULL, 0, "Total length of security descriptor", HFILL }},
17940
17941         { &hf_smb_ea_list_length,
17942                 { "EA List Length", "smb.ea.list_length", FT_UINT32, BASE_DEC,
17943                 NULL, 0, "Total length of extended attributes", HFILL }},
17944
17945         { &hf_smb_ea_flags,
17946                 { "EA Flags", "smb.ea.flags", FT_UINT8, BASE_HEX,
17947                 NULL, 0, "EA Flags", HFILL }},
17948
17949         { &hf_smb_ea_name_length,
17950                 { "EA Name Length", "smb.ea.name_length", FT_UINT8, BASE_DEC,
17951                 NULL, 0, "EA Name Length", HFILL }},
17952
17953         { &hf_smb_ea_data_length,
17954                 { "EA Data Length", "smb.ea.data_length", FT_UINT16, BASE_DEC,
17955                 NULL, 0, "EA Data Length", HFILL }},
17956
17957         { &hf_smb_ea_name,
17958                 { "EA Name", "smb.ea.name", FT_STRING, BASE_NONE,
17959                 NULL, 0, "EA Name", HFILL }},
17960
17961         { &hf_smb_ea_data,
17962                 { "EA Data", "smb.ea.data", FT_BYTES, BASE_NONE,
17963                 NULL, 0, "EA Data", HFILL }},
17964
17965         { &hf_smb_file_name_len,
17966                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
17967                 NULL, 0, "Length of File Name", HFILL }},
17968
17969         { &hf_smb_nt_impersonation_level,
17970                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
17971                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
17972
17973         { &hf_smb_nt_security_flags_context_tracking,
17974                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
17975                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
17976
17977         { &hf_smb_nt_security_flags_effective_only,
17978                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
17979                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
17980
17981         { &hf_smb_nt_access_mask_generic_read,
17982                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
17983                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
17984
17985         { &hf_smb_nt_access_mask_generic_write,
17986                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
17987                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
17988
17989         { &hf_smb_nt_access_mask_generic_execute,
17990                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
17991                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
17992
17993         { &hf_smb_nt_access_mask_generic_all,
17994                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
17995                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
17996
17997         { &hf_smb_nt_access_mask_maximum_allowed,
17998                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
17999                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
18000
18001         { &hf_smb_nt_access_mask_system_security,
18002                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
18003                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
18004
18005         { &hf_smb_nt_access_mask_synchronize,
18006                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
18007                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
18008
18009         { &hf_smb_nt_access_mask_write_owner,
18010                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
18011                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
18012
18013         { &hf_smb_nt_access_mask_write_dac,
18014                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
18015                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
18016
18017         { &hf_smb_nt_access_mask_read_control,
18018                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
18019                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
18020
18021         { &hf_smb_nt_access_mask_delete,
18022                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
18023                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
18024
18025         { &hf_smb_nt_access_mask_write_attributes,
18026                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
18027                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
18028
18029         { &hf_smb_nt_access_mask_read_attributes,
18030                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
18031                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
18032
18033         { &hf_smb_nt_access_mask_delete_child,
18034                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
18035                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
18036
18037         /*
18038          * "Execute" for files, "traverse" for directories.
18039          */
18040         { &hf_smb_nt_access_mask_execute,
18041                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
18042                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
18043
18044         { &hf_smb_nt_access_mask_write_ea,
18045                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
18046                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
18047
18048         { &hf_smb_nt_access_mask_read_ea,
18049                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
18050                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
18051
18052         /*
18053          * "Append data" for files, "add subdirectory" for directories,
18054          * "create pipe instance" for named pipes.
18055          */
18056         { &hf_smb_nt_access_mask_append,
18057                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
18058                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
18059
18060         /*
18061          * "Write data" for files and pipes, "add file" for directory.
18062          */
18063         { &hf_smb_nt_access_mask_write,
18064                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
18065                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
18066
18067         /*
18068          * "Read data" for files and pipes, "list directory" for directory.
18069          */
18070         { &hf_smb_nt_access_mask_read,
18071                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
18072                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
18073
18074         { &hf_smb_nt_create_bits_oplock,
18075                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
18076                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
18077
18078         { &hf_smb_nt_create_bits_boplock,
18079                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
18080                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
18081
18082         { &hf_smb_nt_create_bits_dir,
18083                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
18084                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
18085
18086         { &hf_smb_nt_create_bits_ext_resp,
18087           { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32, 
18088             TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
18089
18090         { &hf_smb_nt_create_options_directory_file,
18091                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
18092                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
18093
18094         { &hf_smb_nt_create_options_write_through,
18095                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
18096                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
18097
18098         { &hf_smb_nt_create_options_sequential_only,
18099                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
18100                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
18101
18102         { &hf_smb_nt_create_options_sync_io_alert,
18103                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
18104                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
18105
18106         { &hf_smb_nt_create_options_sync_io_nonalert,
18107                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
18108                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
18109
18110         { &hf_smb_nt_create_options_non_directory_file,
18111                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
18112                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
18113
18114         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
18115            and "NtOpenFile()"; is that sent over the wire?  Network
18116            Monitor thinks so, but its author may just have grabbed
18117            the flag bits from a system header file. */
18118
18119         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
18120            and "NtOpenFile()"; is that sent over the wire?  NetMon
18121            thinks so, but see previous comment. */
18122
18123         { &hf_smb_nt_create_options_no_ea_knowledge,
18124                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
18125                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
18126
18127         { &hf_smb_nt_create_options_eight_dot_three_only,
18128                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
18129                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
18130
18131         { &hf_smb_nt_create_options_random_access,
18132                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
18133                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
18134
18135         { &hf_smb_nt_create_options_delete_on_close,
18136                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
18137                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
18138
18139         /* 0x00002000 is "open by FID", or something such as that (which
18140            I suspect is like "open by inumber" on UNIX), at least in
18141            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
18142            wire?  NetMon thinks so, but see previous comment. */
18143
18144         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
18145            and "NtOpenFile()"; is that sent over the wire?  NetMon
18146            thinks so, but see previous comment. */
18147
18148         { &hf_smb_nt_share_access_read,
18149                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
18150                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
18151
18152         { &hf_smb_nt_share_access_write,
18153                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
18154                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
18155
18156         { &hf_smb_nt_share_access_delete,
18157                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
18158                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
18159
18160         { &hf_smb_file_eattr_read_only,
18161                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
18162                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
18163
18164         { &hf_smb_file_eattr_hidden,
18165                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
18166                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
18167
18168         { &hf_smb_file_eattr_system,
18169                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
18170                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
18171
18172         { &hf_smb_file_eattr_volume,
18173                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
18174                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
18175
18176         { &hf_smb_file_eattr_directory,
18177                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
18178                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
18179
18180         { &hf_smb_file_eattr_archive,
18181                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
18182                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
18183
18184         { &hf_smb_file_eattr_device,
18185                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
18186                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
18187
18188         { &hf_smb_file_eattr_normal,
18189                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
18190                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
18191
18192         { &hf_smb_file_eattr_temporary,
18193                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
18194                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
18195
18196         { &hf_smb_file_eattr_sparse,
18197                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
18198                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
18199
18200         { &hf_smb_file_eattr_reparse,
18201                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
18202                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
18203
18204         { &hf_smb_file_eattr_compressed,
18205                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
18206                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
18207
18208         { &hf_smb_file_eattr_offline,
18209                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
18210                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
18211
18212         { &hf_smb_file_eattr_not_content_indexed,
18213                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
18214                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
18215
18216         { &hf_smb_file_eattr_encrypted,
18217                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
18218                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
18219
18220         { &hf_smb_sec_desc_len,
18221                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
18222                 NULL, 0, "Security Descriptor Length", HFILL }},
18223
18224         { &hf_smb_nt_qsd_owner,
18225                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
18226                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
18227
18228         { &hf_smb_nt_qsd_group,
18229                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
18230                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
18231
18232         { &hf_smb_nt_qsd_dacl,
18233                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
18234                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
18235
18236         { &hf_smb_nt_qsd_sacl,
18237                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
18238                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
18239
18240         { &hf_smb_extended_attributes,
18241                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
18242                 NULL, 0, "Extended Attributes", HFILL }},
18243
18244         { &hf_smb_oplock_level,
18245                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
18246                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
18247
18248         { &hf_smb_create_action,
18249                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
18250                 VALS(oa_open_vals), 0, "Type of action taken", HFILL }},
18251
18252         { &hf_smb_file_id,
18253                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
18254                 NULL, 0, "Server unique file ID", HFILL }},
18255
18256         { &hf_smb_ea_error_offset,
18257                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
18258                 NULL, 0, "Offset into EA list if EA error", HFILL }},
18259
18260         { &hf_smb_end_of_file,
18261                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
18262                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
18263
18264         { &hf_smb_device_type,
18265                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
18266                 VALS(device_type_vals), 0, "Type of device", HFILL }},
18267
18268         { &hf_smb_is_directory,
18269                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
18270                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
18271
18272         { &hf_smb_next_entry_offset,
18273                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
18274                 NULL, 0, "Offset to next entry", HFILL }},
18275
18276         { &hf_smb_change_time,
18277                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
18278                 NULL, 0, "Last Change Time", HFILL }},
18279
18280         { &hf_smb_setup_len,
18281                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
18282                 NULL, 0, "Length of printer setup data", HFILL }},
18283
18284         { &hf_smb_print_mode,
18285                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
18286                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
18287
18288         { &hf_smb_print_identifier,
18289                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
18290                 NULL, 0, "Identifier string for this print job", HFILL }},
18291
18292         { &hf_smb_restart_index,
18293                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
18294                 NULL, 0, "Index of entry after last returned", HFILL }},
18295
18296         { &hf_smb_print_queue_date,
18297                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
18298                 NULL, 0, "Date when this entry was queued", HFILL }},
18299
18300         { &hf_smb_print_queue_dos_date,
18301                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
18302                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
18303
18304         { &hf_smb_print_queue_dos_time,
18305                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
18306                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
18307
18308         { &hf_smb_print_status,
18309                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
18310                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
18311
18312         { &hf_smb_print_spool_file_number,
18313                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
18314                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
18315
18316         { &hf_smb_print_spool_file_size,
18317                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
18318                 NULL, 0, "Number of bytes in spool file", HFILL }},
18319
18320         { &hf_smb_print_spool_file_name,
18321                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
18322                 NULL, 0, "Name of client that submitted this job", HFILL }},
18323
18324         { &hf_smb_start_index,
18325                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
18326                 NULL, 0, "First queue entry to return", HFILL }},
18327
18328         { &hf_smb_originator_name,
18329                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
18330                 NULL, 0, "Name of sender of message", HFILL }},
18331
18332         { &hf_smb_destination_name,
18333                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
18334                 NULL, 0, "Name of recipient of message", HFILL }},
18335
18336         { &hf_smb_message_len,
18337                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
18338                 NULL, 0, "Length of message", HFILL }},
18339
18340         { &hf_smb_message,
18341                 { "Message", "smb.message", FT_STRING, BASE_NONE,
18342                 NULL, 0, "Message text", HFILL }},
18343
18344         { &hf_smb_mgid,
18345                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
18346                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
18347
18348         { &hf_smb_forwarded_name,
18349                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
18350                 NULL, 0, "Recipient name being forwarded", HFILL }},
18351
18352         { &hf_smb_machine_name,
18353                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
18354                 NULL, 0, "Name of target machine", HFILL }},
18355
18356         { &hf_smb_cancel_to,
18357                 { "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
18358                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
18359
18360         { &hf_smb_trans2_subcmd,
18361                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
18362                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
18363
18364         { &hf_smb_trans_name,
18365                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
18366                 NULL, 0, "Name of transaction", HFILL }},
18367
18368         { &hf_smb_transaction_flags_dtid,
18369                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
18370                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
18371
18372         { &hf_smb_transaction_flags_owt,
18373                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
18374                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
18375
18376         { &hf_smb_search_count,
18377                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
18378                 NULL, 0, "Maximum number of search entries to return", HFILL }},
18379
18380         { &hf_smb_search_pattern,
18381                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
18382                 NULL, 0, "Search Pattern", HFILL }},
18383
18384         { &hf_smb_ff2_backup,
18385                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
18386                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
18387
18388         { &hf_smb_ff2_continue,
18389                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
18390                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
18391
18392         { &hf_smb_ff2_resume,
18393                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
18394                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
18395
18396         { &hf_smb_ff2_close_eos,
18397                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
18398                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
18399
18400         { &hf_smb_ff2_close,
18401                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
18402                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
18403
18404         { &hf_smb_ff2_information_level,
18405                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
18406                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
18407
18408         { &hf_smb_qpi_loi,
18409                 { "Level of Interest", "smb.qpi_loi", FT_UINT16, BASE_DEC,
18410                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] QUERY_{FILE,PATH}_INFO commands", HFILL }},
18411
18412         { &hf_smb_spi_loi,
18413                 { "Level of Interest", "smb.spi_loi", FT_UINT16, BASE_DEC,
18414                 VALS(spi_loi_vals), 0, "Level of interest for TRANSACTION[2] SET_{FILE,PATH}_INFO commands", HFILL }},
18415
18416 #if 0
18417         { &hf_smb_sfi_writetru,
18418                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
18419                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
18420
18421         { &hf_smb_sfi_caching,
18422                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
18423                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
18424 #endif
18425
18426         { &hf_smb_storage_type,
18427                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
18428                 NULL, 0, "Type of storage", HFILL }},
18429
18430         { &hf_smb_resume,
18431                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
18432                 NULL, 0, "Resume Key", HFILL }},
18433
18434         { &hf_smb_max_referral_level,
18435                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
18436                 NULL, 0, "Latest referral version number understood", HFILL }},
18437
18438         { &hf_smb_qfsi_information_level,
18439                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_HEX,
18440                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
18441
18442         { &hf_smb_nt_rename_level,
18443                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
18444                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
18445
18446         { &hf_smb_cluster_count,
18447                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
18448                 NULL, 0, "Number of clusters", HFILL }},
18449
18450         { &hf_smb_number_of_links,
18451                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
18452                 NULL, 0, "Number of hard links to the file", HFILL }},
18453
18454         { &hf_smb_delete_pending,
18455                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
18456                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
18457
18458         { &hf_smb_index_number,
18459                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
18460                 NULL, 0, "File system unique identifier", HFILL }},
18461
18462         { &hf_smb_current_offset,
18463                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
18464                 NULL, 0, "Current offset in the file", HFILL }},
18465
18466         { &hf_smb_t2_alignment,
18467                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
18468                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
18469
18470         { &hf_smb_t2_stream_name_length,
18471                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
18472                 NULL, 0, "Length of stream name", HFILL }},
18473
18474         { &hf_smb_t2_stream_size,
18475                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
18476                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18477
18478         { &hf_smb_t2_stream_name,
18479                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
18480                 NULL, 0, "Name of the stream", HFILL }},
18481
18482         { &hf_smb_t2_compressed_file_size,
18483                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
18484                 NULL, 0, "Size of the compressed file", HFILL }},
18485
18486         { &hf_smb_t2_compressed_format,
18487                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
18488                 NULL, 0, "Compression algorithm used", HFILL }},
18489
18490         { &hf_smb_t2_compressed_unit_shift,
18491                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
18492                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18493
18494         { &hf_smb_t2_compressed_chunk_shift,
18495                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
18496                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18497
18498         { &hf_smb_t2_compressed_cluster_shift,
18499                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
18500                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18501
18502         { &hf_smb_t2_marked_for_deletion,
18503                 { "Marked for Deletion", "smb.marked_for_deletion", FT_BOOLEAN, BASE_NONE,
18504                 TFS(&tfs_marked_for_deletion), 0x0, "Marked for deletion?", HFILL }},
18505
18506         { &hf_smb_dfs_path_consumed,
18507                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
18508                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
18509
18510         { &hf_smb_dfs_num_referrals,
18511                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
18512                 NULL, 0, "Number of referrals in this pdu", HFILL }},
18513
18514         { &hf_smb_get_dfs_server_hold_storage,
18515                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
18516                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
18517
18518         { &hf_smb_get_dfs_fielding,
18519                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
18520                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
18521
18522         { &hf_smb_dfs_referral_version,
18523                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
18524                 NULL, 0, "Version of referral element", HFILL }},
18525
18526         { &hf_smb_dfs_referral_size,
18527                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
18528                 NULL, 0, "Size of referral element", HFILL }},
18529
18530         { &hf_smb_dfs_referral_server_type,
18531                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
18532                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
18533
18534         { &hf_smb_dfs_referral_flags_strip,
18535                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
18536                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
18537
18538         { &hf_smb_dfs_referral_node_offset,
18539                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
18540                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
18541
18542         { &hf_smb_dfs_referral_node,
18543                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
18544                 NULL, 0, "Name of entity to visit next", HFILL }},
18545
18546         { &hf_smb_dfs_referral_proximity,
18547                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
18548                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
18549
18550         { &hf_smb_dfs_referral_ttl,
18551                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
18552                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
18553
18554         { &hf_smb_dfs_referral_path_offset,
18555                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
18556                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
18557
18558         { &hf_smb_dfs_referral_path,
18559                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
18560                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
18561
18562         { &hf_smb_dfs_referral_alt_path_offset,
18563                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
18564                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
18565
18566         { &hf_smb_dfs_referral_alt_path,
18567                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
18568                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
18569
18570         { &hf_smb_end_of_search,
18571                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
18572                 NULL, 0, "Was last entry returned?", HFILL }},
18573
18574         { &hf_smb_last_name_offset,
18575                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
18576                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
18577
18578         { &hf_smb_fn_information_level,
18579                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
18580                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
18581
18582         { &hf_smb_monitor_handle,
18583                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
18584                 NULL, 0, "Handle for Find Notify operations", HFILL }},
18585
18586         { &hf_smb_change_count,
18587                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
18588                 NULL, 0, "Number of changes to wait for", HFILL }},
18589
18590         { &hf_smb_file_index,
18591                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
18592                 NULL, 0, "File index", HFILL }},
18593
18594         { &hf_smb_short_file_name,
18595                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
18596                 NULL, 0, "Short (8.3) File Name", HFILL }},
18597
18598         { &hf_smb_short_file_name_len,
18599                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
18600                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
18601
18602         { &hf_smb_fs_id,
18603                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
18604                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
18605
18606         { &hf_smb_fs_guid,
18607                 { "FS GUID", "smb.fs_guid", FT_STRING, BASE_NONE,
18608                 NULL, 0, "File System GUID", HFILL }},
18609
18610         { &hf_smb_sector_unit,
18611                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
18612                 NULL, 0, "Sectors per allocation unit", HFILL }},
18613
18614         { &hf_smb_fs_units,
18615                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
18616                 NULL, 0, "Total number of units on this filesystem", HFILL }},
18617
18618         { &hf_smb_fs_sector,
18619                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
18620                 NULL, 0, "Bytes per sector", HFILL }},
18621
18622         { &hf_smb_avail_units,
18623                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
18624                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
18625
18626         { &hf_smb_volume_serial_num,
18627                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
18628                 NULL, 0, "Volume serial number", HFILL }},
18629
18630         { &hf_smb_volume_label_len,
18631                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
18632                 NULL, 0, "Length of volume label", HFILL }},
18633
18634         { &hf_smb_volume_label,
18635                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
18636                 NULL, 0, "Volume label", HFILL }},
18637
18638         { &hf_smb_free_alloc_units64,
18639                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
18640                 NULL, 0, "Number of free allocation units", HFILL }},
18641
18642         { &hf_smb_caller_free_alloc_units64,
18643                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
18644                 NULL, 0, "Number of caller free allocation units", HFILL }},
18645
18646         { &hf_smb_actual_free_alloc_units64,
18647                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
18648                 NULL, 0, "Number of actual free allocation units", HFILL }},
18649
18650         { &hf_smb_soft_quota_limit,
18651                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
18652                 NULL, 0, "Soft Quota treshold", HFILL }},
18653
18654         { &hf_smb_hard_quota_limit,
18655                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
18656                 NULL, 0, "Hard Quota limit", HFILL }},
18657
18658         { &hf_smb_user_quota_used,
18659                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
18660                 NULL, 0, "How much Quota is used by this user", HFILL }},
18661
18662         { &hf_smb_max_name_len,
18663                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
18664                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
18665
18666         { &hf_smb_fs_name_len,
18667                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
18668                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
18669
18670         { &hf_smb_fs_name,
18671                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
18672                 NULL, 0, "Name of filesystem", HFILL }},
18673
18674         { &hf_smb_device_char_removable,
18675                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
18676                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
18677
18678         { &hf_smb_device_char_read_only,
18679                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
18680                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
18681
18682         { &hf_smb_device_char_floppy,
18683                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
18684                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
18685
18686         { &hf_smb_device_char_write_once,
18687                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
18688                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
18689
18690         { &hf_smb_device_char_remote,
18691                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
18692                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
18693
18694         { &hf_smb_device_char_mounted,
18695                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
18696                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
18697
18698         { &hf_smb_device_char_virtual,
18699                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
18700                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
18701
18702         { &hf_smb_fs_attr_css,
18703                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
18704                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
18705
18706         { &hf_smb_fs_attr_cpn,
18707                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
18708                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
18709
18710         { &hf_smb_fs_attr_pacls,
18711                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
18712                 TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
18713
18714         { &hf_smb_fs_attr_fc,
18715                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
18716                 TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
18717
18718         { &hf_smb_fs_attr_vq,
18719                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
18720                 TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
18721
18722         { &hf_smb_fs_attr_dim,
18723                 { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
18724                 TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
18725
18726         { &hf_smb_fs_attr_vic,
18727                 { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
18728                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
18729
18730         { &hf_smb_sec_desc_revision,
18731                 { "Revision", "smb.sec_desc.revision", FT_UINT8, BASE_DEC,
18732                 NULL, 0, "Version of NT Security Descriptor structure", HFILL }},
18733
18734         { &hf_smb_sid,
18735                 { "SID", "smb.sid", FT_STRING, BASE_DEC,
18736                 NULL, 0, "SID: Security Identifier", HFILL }},
18737
18738         { &hf_smb_sid_revision,
18739                 { "Revision", "smb.sid.revision", FT_UINT8, BASE_DEC,
18740                 NULL, 0, "Version of SID structure", HFILL }},
18741
18742         { &hf_smb_sid_num_auth,
18743                 { "Num Auth", "smb.sid.num_auth", FT_UINT8, BASE_DEC,
18744                 NULL, 0, "Number of authorities for this SID", HFILL }},
18745
18746         { &hf_smb_acl_revision,
18747                 { "Revision", "smb.acl.revision", FT_UINT16, BASE_DEC,
18748                 NULL, 0, "Version of NT ACL structure", HFILL }},
18749
18750         { &hf_smb_acl_size,
18751                 { "Size", "smb.acl.size", FT_UINT16, BASE_DEC,
18752                 NULL, 0, "Size of NT ACL structure", HFILL }},
18753
18754         { &hf_smb_acl_num_aces,
18755                 { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
18756                 NULL, 0, "Number of ACE structures for this ACL", HFILL }},
18757
18758         { &hf_smb_user_quota_offset,
18759                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
18760                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
18761
18762         { &hf_smb_ace_type,
18763                 { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
18764                 VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
18765
18766         { &hf_smb_pipe_write_len,
18767                 { "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
18768                 NULL, 0, "Number of bytes written to pipe", HFILL }},
18769
18770         { &hf_smb_ace_size,
18771                 { "Size", "smb.ace.size", FT_UINT16, BASE_DEC,
18772                 NULL, 0, "Size of this ACE", HFILL }},
18773
18774         { &hf_smb_ace_flags_object_inherit,
18775                 { "Object Inherit", "smb.ace.flags.object_inherit", FT_BOOLEAN, 8,
18776                 TFS(&tfs_ace_flags_object_inherit), 0x01, "Will subordinate files inherit this ACE?", HFILL }},
18777
18778         { &hf_smb_ace_flags_container_inherit,
18779                 { "Container Inherit", "smb.ace.flags.container_inherit", FT_BOOLEAN, 8,
18780                 TFS(&tfs_ace_flags_container_inherit), 0x02, "Will subordinate containers inherit this ACE?", HFILL }},
18781
18782         { &hf_smb_ace_flags_non_propagate_inherit,
18783                 { "Non-Propagate Inherit", "smb.ace.flags.non_propagate_inherit", FT_BOOLEAN, 8,
18784                 TFS(&tfs_ace_flags_non_propagate_inherit), 0x04, "Will subordinate object propagate this ACE further?", HFILL }},
18785
18786         { &hf_smb_ace_flags_inherit_only,
18787                 { "Inherit Only", "smb.ace.flags.inherit_only", FT_BOOLEAN, 8,
18788                 TFS(&tfs_ace_flags_inherit_only), 0x08, "Does this ACE apply to the current object?", HFILL }},
18789
18790         { &hf_smb_ace_flags_inherited_ace,
18791                 { "Inherited ACE", "smb.ace.flags.inherited_ace", FT_BOOLEAN, 8,
18792                 TFS(&tfs_ace_flags_inherited_ace), 0x10, "Was this ACE inherited from its parent object?", HFILL }},
18793
18794         { &hf_smb_ace_flags_successful_access,
18795                 { "Audit Successful Accesses", "smb.ace.flags.successful_access", FT_BOOLEAN, 8,
18796                 TFS(&tfs_ace_flags_successful_access), 0x40, "Should successful accesses be audited?", HFILL }},
18797
18798         { &hf_smb_ace_flags_failed_access,
18799                 { "Audit Failed Accesses", "smb.ace.flags.failed_access", FT_BOOLEAN, 8,
18800                 TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
18801
18802         { &hf_smb_sec_desc_type_owner_defaulted,
18803                 { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
18804                 TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
18805
18806         { &hf_smb_sec_desc_type_group_defaulted,
18807                 { "Group Defaulted", "smb.sec_desc.type.group_defaulted", FT_BOOLEAN, 16,
18808                 TFS(&tfs_sec_desc_type_group_defaulted), 0x0002, "Is Group Defaulted?", HFILL }},
18809
18810         { &hf_smb_sec_desc_type_dacl_present,
18811                 { "DACL Present", "smb.sec_desc.type.dacl_present", FT_BOOLEAN, 16,
18812                 TFS(&tfs_sec_desc_type_dacl_present), 0x0004, "Does this SecDesc have DACL present?", HFILL }},
18813
18814         { &hf_smb_sec_desc_type_dacl_defaulted,
18815                 { "DACL Defaulted", "smb.sec_desc.type.dacl_defaulted", FT_BOOLEAN, 16,
18816                 TFS(&tfs_sec_desc_type_dacl_defaulted), 0x0008, "Does this SecDesc have DACL Defaulted?", HFILL }},
18817
18818         { &hf_smb_sec_desc_type_sacl_present,
18819                 { "SACL Present", "smb.sec_desc.type.sacl_present", FT_BOOLEAN, 16,
18820                 TFS(&tfs_sec_desc_type_sacl_present), 0x0010, "Is the SACL present?", HFILL }},
18821
18822         { &hf_smb_sec_desc_type_sacl_defaulted,
18823                 { "SACL Defaulted", "smb.sec_desc.type.sacl_defaulted", FT_BOOLEAN, 16,
18824                 TFS(&tfs_sec_desc_type_sacl_defaulted), 0x0020, "Does this SecDesc have SACL Defaulted?", HFILL }},
18825
18826         { &hf_smb_sec_desc_type_dacl_auto_inherit_req,
18827                 { "DACL Auto Inherit Required", "smb.sec_desc.type.dacl_auto_inherit_req", FT_BOOLEAN, 16,
18828                 TFS(&tfs_sec_desc_type_dacl_auto_inherit_req), 0x0100, "Does this SecDesc have DACL Auto Inherit Required set?", HFILL }},
18829
18830         { &hf_smb_sec_desc_type_sacl_auto_inherit_req,
18831                 { "SACL Auto Inherit Required", "smb.sec_desc.type.sacl_auto_inherit_req", FT_BOOLEAN, 16,
18832                 TFS(&tfs_sec_desc_type_sacl_auto_inherit_req), 0x0200, "Does this SecDesc have SACL Auto Inherit Required set?", HFILL }},
18833
18834         { &hf_smb_sec_desc_type_dacl_auto_inherited,
18835                 { "DACL Auto Inherited", "smb.sec_desc.type.dacl_auto_inherited", FT_BOOLEAN, 16,
18836                 TFS(&tfs_sec_desc_type_dacl_auto_inherited), 0x0400, "Is this DACL auto inherited", HFILL }},
18837
18838         { &hf_smb_sec_desc_type_sacl_auto_inherited,
18839                 { "SACL Auto Inherited", "smb.sec_desc.type.sacl_auto_inherited", FT_BOOLEAN, 16,
18840                 TFS(&tfs_sec_desc_type_sacl_auto_inherited), 0x0800, "Is this SACL auto inherited", HFILL }},
18841
18842         { &hf_smb_sec_desc_type_dacl_protected,
18843                 { "DACL Protected", "smb.sec_desc.type.dacl_protected", FT_BOOLEAN, 16,
18844                 TFS(&tfs_sec_desc_type_dacl_protected), 0x1000, "Is the DACL structure protected?", HFILL }},
18845
18846         { &hf_smb_sec_desc_type_sacl_protected,
18847                 { "SACL Protected", "smb.sec_desc.type.sacl_protected", FT_BOOLEAN, 16,
18848                 TFS(&tfs_sec_desc_type_sacl_protected), 0x2000, "Is the SACL structure protected?", HFILL }},
18849
18850         { &hf_smb_sec_desc_type_self_relative,
18851                 { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
18852                 TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
18853
18854         { &hf_smb_quota_flags_deny_disk,
18855                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
18856                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
18857
18858         { &hf_smb_quota_flags_log_limit,
18859                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
18860                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
18861
18862         { &hf_smb_quota_flags_log_warning,
18863                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
18864                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
18865
18866         { &hf_smb_quota_flags_enabled,
18867                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
18868                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
18869
18870         { &hf_smb_segment_overlap,
18871                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18872                         "Fragment overlaps with other fragments", HFILL }},
18873
18874         { &hf_smb_segment_overlap_conflict,
18875                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18876                         "Overlapping fragments contained conflicting data", HFILL }},
18877
18878         { &hf_smb_segment_multiple_tails,
18879                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18880                         "Several tails were found when defragmenting the packet", HFILL }},
18881
18882         { &hf_smb_segment_too_long_fragment,
18883                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18884                         "Fragment contained data past end of packet", HFILL }},
18885
18886         { &hf_smb_segment_error,
18887                 { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18888                         "Defragmentation error due to illegal fragments", HFILL }},
18889
18890         { &hf_smb_segment,
18891                 { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18892                         "SMB Segment", HFILL }},
18893
18894         { &hf_smb_segments,
18895                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
18896                         "SMB Segments", HFILL }},
18897
18898         { &hf_smb_unix_major_version,
18899           { "Major Version", "smb.unix.major_version", FT_UINT16, BASE_DEC,
18900             NULL, 0, "UNIX Major Version", HFILL }},
18901
18902         { &hf_smb_unix_minor_version,
18903           { "Minor Version", "smb.unix.minor_version", FT_UINT16, BASE_DEC,
18904             NULL, 0, "UNIX Minor Version", HFILL }},
18905
18906         { &hf_smb_unix_capability_fcntl,
18907           { "FCNTL Capability", "smb.unix.capability.fcntl", FT_BOOLEAN, 32,
18908                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
18909
18910         { &hf_smb_unix_capability_posix_acl,
18911           { "POSIX ACL Capability", "smb.unix.capability.posix_acl", FT_BOOLEAN, 32,
18912                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
18913
18914         { &hf_smb_unix_file_size,
18915           { "File size", "smb.unix.file.size", FT_UINT64, BASE_DEC,
18916             NULL, 0, "", HFILL }},
18917
18918         { &hf_smb_unix_file_num_bytes,
18919           { "Number of bytes", "smb.unix.file.num_bytes", FT_UINT64, BASE_DEC,
18920             NULL, 0, "Number of bytes used to store the file", HFILL }},
18921
18922         { &hf_smb_unix_file_last_status,
18923           { "Last status change", "smb.unix.file.stime", FT_ABSOLUTE_TIME, BASE_NONE,
18924             NULL, 0, "", HFILL }},
18925
18926         { &hf_smb_unix_file_last_access,
18927           { "Last access", "smb.unix.file.atime", FT_ABSOLUTE_TIME, BASE_NONE,
18928             NULL, 0, "", HFILL }},
18929
18930         { &hf_smb_unix_file_last_change,
18931           { "Last modification", "smb.unix.file.mtime", FT_ABSOLUTE_TIME, BASE_NONE,
18932             NULL, 0, "", HFILL }},
18933
18934         { &hf_smb_unix_file_uid,
18935           { "UID", "smb.unix.file.uid", FT_UINT64, BASE_DEC,
18936             NULL, 0, "", HFILL }},
18937
18938         { &hf_smb_unix_file_gid,
18939           { "GID", "smb.unix.file.gid", FT_UINT64, BASE_DEC,
18940             NULL, 0, "", HFILL }},
18941
18942         { &hf_smb_unix_file_type,
18943           { "File type", "smb.unix.file.file_type", FT_UINT32, BASE_DEC,
18944             VALS(unix_file_type_vals), 0, "", HFILL }},
18945
18946         { &hf_smb_unix_file_dev_major,
18947           { "Major device", "smb.unix.file.dev_major", FT_UINT64, BASE_HEX,
18948             NULL, 0, "", HFILL }},
18949
18950         { &hf_smb_unix_file_dev_minor,
18951           { "Minor device", "smb.unix.file.dev_minor", FT_UINT64, BASE_HEX,
18952             NULL, 0, "", HFILL }},
18953
18954         { &hf_smb_unix_file_unique_id,
18955           { "Unique ID", "smb.unix.file.unique_id", FT_UINT64, BASE_HEX,
18956             NULL, 0, "", HFILL }},
18957
18958         { &hf_smb_unix_file_permissions,
18959           { "File permissions", "smb.unix.file.perms", FT_UINT64, BASE_HEX,
18960             NULL, 0, "", HFILL }},
18961
18962         { &hf_smb_unix_file_nlinks,
18963           { "Num links", "smb.unix.file.num_links", FT_UINT64, BASE_DEC,
18964             NULL, 0, "", HFILL }},
18965
18966         { &hf_smb_unix_file_link_dest,
18967           { "Link destination", "smb.unix.file.link_dest", FT_STRING, 
18968             BASE_NONE, NULL, 0, "", HFILL }},
18969
18970         { &hf_smb_unix_find_file_nextoffset,
18971           { "Next entry offset", "smb.unix.find_file.next_offset", FT_UINT32, BASE_DEC,
18972             NULL, 0, "", HFILL }},
18973
18974         { &hf_smb_unix_find_file_resumekey,
18975           { "Resume key", "smb.unix.find_file.resume_key", FT_UINT32, BASE_DEC,
18976             NULL, 0, "", HFILL }},
18977
18978                 /* Access masks */
18979
18980                 { &hf_smb_access_mask,
18981                   { "Access required", "smb.access_mask",
18982                     FT_UINT32, BASE_HEX, NULL, 0x0, "Access mask",
18983                     HFILL }},
18984                 { &hf_access_generic_read,
18985                   { "Generic read", "nt.access_mask.generic_read",
18986                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18987                     GENERIC_READ_ACCESS, "Generic read", HFILL }},
18988
18989                 { &hf_access_generic_write,
18990                   { "Generic write", "nt.access_mask.generic_write",
18991                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18992                     GENERIC_WRITE_ACCESS, "Generic write", HFILL }},
18993
18994                 { &hf_access_generic_execute,
18995                   { "Generic execute", "nt.access_mask.generic_execute",
18996                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18997                     GENERIC_EXECUTE_ACCESS, "Generic execute", HFILL }},
18998
18999                 { &hf_access_generic_all,
19000                   { "Generic all", "nt.access_mask.generic_all",
19001                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19002                     GENERIC_ALL_ACCESS, "Generic all", HFILL }},
19003
19004                 { &hf_access_maximum_allowed,
19005                   { "Maximum allowed", "nt.access_mask.maximum_allowed",
19006                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19007                     MAXIMUM_ALLOWED_ACCESS, "Maximum allowed", HFILL }},
19008
19009                 { &hf_access_sacl,
19010                   { "Access SACL", "nt.access_mask.access_sacl",
19011                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19012                     ACCESS_SACL_ACCESS, "Access SACL", HFILL }},
19013
19014                 { &hf_access_standard_read_control,
19015                   { "Read control", "nt.access_mask.read_control",
19016                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19017                     READ_CONTROL_ACCESS, "Read control", HFILL }},
19018
19019                 { &hf_access_standard_delete,
19020                   { "Delete", "nt.access_mask.delete",
19021                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19022                     DELETE_ACCESS, "Delete", HFILL }},
19023
19024                 { &hf_access_standard_synchronise,
19025                   { "Synchronise", "nt.access_mask.synchronise",
19026                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19027                     SYNCHRONIZE_ACCESS, "Synchronise", HFILL }},
19028
19029                 { &hf_access_standard_write_dac,
19030                   { "Write DAC", "nt.access_mask.write_dac",
19031                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19032                     WRITE_DAC_ACCESS, "Write DAC", HFILL }},
19033
19034                 { &hf_access_standard_write_owner,
19035                   { "Write owner", "nt.access_mask.write_owner",
19036                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19037                     WRITE_OWNER_ACCESS, "Write owner", HFILL }},
19038
19039                 { &hf_access_specific_15,
19040                   { "Specific access, bit 15", "nt.access_mask.specific_15",
19041                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19042                     0x8000, "Specific access, bit 15", HFILL }},
19043
19044                 { &hf_access_specific_14,
19045                   { "Specific access, bit 14", "nt.access_mask.specific_14",
19046                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19047                     0x4000, "Specific access, bit 14", HFILL }},
19048
19049                 { &hf_access_specific_13,
19050                   { "Specific access, bit 13", "nt.access_mask.specific_13",
19051                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19052                     0x2000, "Specific access, bit 13", HFILL }},
19053
19054                 { &hf_access_specific_12,
19055                   { "Specific access, bit 12", "nt.access_mask.specific_12",
19056                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19057                     0x1000, "Specific access, bit 12", HFILL }},
19058
19059                 { &hf_access_specific_11,
19060                   { "Specific access, bit 11", "nt.access_mask.specific_11",
19061                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19062                     0x0800, "Specific access, bit 11", HFILL }},
19063
19064                 { &hf_access_specific_10,
19065                   { "Specific access, bit 10", "nt.access_mask.specific_10",
19066                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19067                     0x0400, "Specific access, bit 10", HFILL }},
19068
19069                 { &hf_access_specific_9,
19070                   { "Specific access, bit 9", "nt.access_mask.specific_9",
19071                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19072                     0x0200, "Specific access, bit 9", HFILL }},
19073
19074                 { &hf_access_specific_8,
19075                   { "Specific access, bit 8", "nt.access_mask.specific_8",
19076                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19077                     0x0100, "Specific access, bit 8", HFILL }},
19078
19079                 { &hf_access_specific_7,
19080                   { "Specific access, bit 7", "nt.access_mask.specific_7",
19081                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19082                     0x0080, "Specific access, bit 7", HFILL }},
19083
19084                 { &hf_access_specific_6,
19085                   { "Specific access, bit 6", "nt.access_mask.specific_6",
19086                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19087                     0x0040, "Specific access, bit 6", HFILL }},
19088
19089                 { &hf_access_specific_5,
19090                   { "Specific access, bit 5", "nt.access_mask.specific_5",
19091                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19092                     0x0020, "Specific access, bit 5", HFILL }},
19093
19094                 { &hf_access_specific_4,
19095                   { "Specific access, bit 4", "nt.access_mask.specific_4",
19096                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19097                     0x0010, "Specific access, bit 4", HFILL }},
19098
19099                 { &hf_access_specific_3,
19100                   { "Specific access, bit 3", "nt.access_mask.specific_3",
19101                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19102                     0x0008, "Specific access, bit 3", HFILL }},
19103
19104                 { &hf_access_specific_2,
19105                   { "Specific access, bit 2", "nt.access_mask.specific_2",
19106                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19107                     0x0004, "Specific access, bit 2", HFILL }},
19108
19109                 { &hf_access_specific_1,
19110                   { "Specific access, bit 1", "nt.access_mask.specific_1",
19111                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19112                     0x0002, "Specific access, bit 1", HFILL }},
19113
19114                 { &hf_access_specific_0,
19115                   { "Specific access, bit 0", "nt.access_mask.specific_0",
19116                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19117                     0x0001, "Specific access, bit 0", HFILL }}
19118         };
19119
19120         static gint *ett[] = {
19121                 &ett_smb,
19122                 &ett_smb_hdr,
19123                 &ett_smb_command,
19124                 &ett_smb_fileattributes,
19125                 &ett_smb_capabilities,
19126                 &ett_smb_aflags,
19127                 &ett_smb_dialect,
19128                 &ett_smb_dialects,
19129                 &ett_smb_mode,
19130                 &ett_smb_rawmode,
19131                 &ett_smb_flags,
19132                 &ett_smb_flags2,
19133                 &ett_smb_desiredaccess,
19134                 &ett_smb_search,
19135                 &ett_smb_file,
19136                 &ett_smb_openfunction,
19137                 &ett_smb_filetype,
19138                 &ett_smb_openaction,
19139                 &ett_smb_writemode,
19140                 &ett_smb_lock_type,
19141                 &ett_smb_ssetupandxaction,
19142                 &ett_smb_optionsup,
19143                 &ett_smb_time_date,
19144                 &ett_smb_move_copy_flags,
19145                 &ett_smb_file_attributes,
19146                 &ett_smb_search_resume_key,
19147                 &ett_smb_search_dir_info,
19148                 &ett_smb_unlocks,
19149                 &ett_smb_unlock,
19150                 &ett_smb_locks,
19151                 &ett_smb_lock,
19152                 &ett_smb_open_flags,
19153                 &ett_smb_ipc_state,
19154                 &ett_smb_open_action,
19155                 &ett_smb_setup_action,
19156                 &ett_smb_connect_flags,
19157                 &ett_smb_connect_support_bits,
19158                 &ett_smb_nt_access_mask,
19159                 &ett_smb_nt_create_bits,
19160                 &ett_smb_nt_create_options,
19161                 &ett_smb_nt_share_access,
19162                 &ett_smb_nt_security_flags,
19163                 &ett_smb_nt_trans_setup,
19164                 &ett_smb_nt_trans_data,
19165                 &ett_smb_nt_trans_param,
19166                 &ett_smb_nt_notify_completion_filter,
19167                 &ett_smb_nt_ioctl_flags,
19168                 &ett_smb_security_information_mask,
19169                 &ett_smb_print_queue_entry,
19170                 &ett_smb_transaction_flags,
19171                 &ett_smb_transaction_params,
19172                 &ett_smb_find_first2_flags,
19173 #if 0
19174                 &ett_smb_ioflag,
19175 #endif
19176                 &ett_smb_transaction_data,
19177                 &ett_smb_stream_info,
19178                 &ett_smb_dfs_referrals,
19179                 &ett_smb_dfs_referral,
19180                 &ett_smb_dfs_referral_flags,
19181                 &ett_smb_get_dfs_flags,
19182                 &ett_smb_ff2_data,
19183                 &ett_smb_device_characteristics,
19184                 &ett_smb_fs_attributes,
19185                 &ett_smb_segments,
19186                 &ett_smb_segment,
19187                 &ett_smb_sec_desc,
19188                 &ett_smb_sid,
19189                 &ett_smb_acl,
19190                 &ett_smb_ace,
19191                 &ett_smb_ace_flags,
19192                 &ett_smb_sec_desc_type,
19193                 &ett_smb_quotaflags,
19194                 &ett_smb_secblob,
19195                 &ett_smb_mac_support_flags,
19196                 &ett_nt_access_mask,
19197                 &ett_nt_access_mask_generic,
19198                 &ett_nt_access_mask_standard,
19199                 &ett_nt_access_mask_specific,
19200                 &ett_smb_unicode_password,
19201                 &ett_smb_ea,
19202                 &ett_smb_unix_capabilities
19203         };
19204         module_t *smb_module;
19205
19206         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
19207             "SMB", "smb");
19208         proto_register_subtree_array(ett, array_length(ett));
19209         proto_register_field_array(proto_smb, hf, array_length(hf));
19210
19211         register_smb_common(proto_smb);
19212
19213         register_init_routine(&smb_init_protocol);
19214         smb_module = prefs_register_protocol(proto_smb, NULL);
19215         prefs_register_bool_preference(smb_module, "trans_reassembly",
19216                 "Reassemble SMB Transaction payload",
19217                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
19218                 &smb_trans_reassembly);
19219         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
19220                 "Reassemble DCERPC over SMB",
19221                 "Whether the dissector should reassemble DCERPC over SMB commands",
19222                 &smb_dcerpc_reassembly);
19223         prefs_register_bool_preference(smb_module, "sid_name_snooping",
19224                 "Snoop SID to Name mappings",
19225                 "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
19226                 &sid_name_snooping);
19227
19228         register_init_routine(smb_trans_reassembly_init);
19229         smb_tap = register_tap("smb");
19230 }
19231
19232 void
19233 proto_reg_handoff_smb(void)
19234 {
19235         dissector_handle_t smb_handle;
19236
19237         gssapi_handle = find_dissector("gssapi");
19238         ntlmssp_handle = find_dissector("ntlmssp");
19239
19240         heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
19241         heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
19242         heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
19243         smb_handle = create_dissector_handle(dissect_smb, proto_smb);
19244         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
19245         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
19246         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER,
19247             smb_handle);
19248 }