in ReadAndX
[metze/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.370 2003/09/28 00:11:01 sahlberg Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  *
12  * Copied from packet-pop.c
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <stdio.h>
34
35 #include <time.h>
36 #include <string.h>
37 #include <glib.h>
38 #include <ctype.h>
39 #include <epan/int-64bit.h>
40 #include <epan/packet.h>
41 #include <epan/conversation.h>
42 #include "smb.h"
43 #include "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          * XXX if maxcount high is 0xFFFFFFFF we assume it is just padding
5331          * bytes and we just ignore it.
5332          */
5333         /* Amasingly enough, this really is 4 bytes, according to the SNIA spec */
5334         maxcnt_high = tvb_get_letohl(tvb, offset);
5335         if(maxcnt_high==0xffffffff){
5336                 maxcnt_high=0;
5337         } else {
5338                 proto_tree_add_uint(tree, hf_smb_max_count_high, tvb, offset, 4, maxcnt_high);
5339         }
5340
5341         offset += 4;
5342
5343         maxcnt=maxcnt_high;
5344         maxcnt=(maxcnt<<16)|maxcnt_low;
5345
5346         if (check_col(pinfo->cinfo, COL_INFO))
5347                 col_append_fstr(pinfo->cinfo, COL_INFO,
5348                                 ", %u byte%s at offset %u", maxcnt,
5349                                 (maxcnt == 1) ? "" : "s", ofs);
5350
5351         /* remaining */
5352         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5353         offset += 2;
5354
5355         if(wc==12){
5356                 /* high offset */
5357                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5358                 offset += 4;
5359         }
5360
5361         BYTE_COUNT;
5362
5363         END_OF_SMB
5364
5365         /* call AndXCommand (if there are any) */
5366         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5367
5368         return offset;
5369 }
5370
5371 static int
5372 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5373 {
5374         guint8  wc, cmd=0xff;
5375         guint16 andxoffset=0, bc, datalen_low, datalen_high, dataoffset=0;
5376         guint32 datalen=0;
5377         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5378         int fid=0;
5379
5380         WORD_COUNT;
5381
5382         /* next smb command */
5383         cmd = tvb_get_guint8(tvb, offset);
5384         if(cmd!=0xff){
5385                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5386         } else {
5387                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5388         }
5389         offset += 1;
5390
5391         /* reserved byte */
5392         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5393         offset += 1;
5394
5395         /* andxoffset */
5396         andxoffset = tvb_get_letohs(tvb, offset);
5397         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5398         offset += 2;
5399
5400         /* If we have seen the request, then print which FID this refers to */
5401         /* first check if we have seen the request */
5402         if(si->sip != NULL && si->sip->frame_req>0){
5403                 fid=(int)si->sip->extra_info;
5404                 add_fid(tvb, pinfo, tree, 0, 0, fid);
5405         }
5406
5407         /* remaining */
5408         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5409         offset += 2;
5410
5411         /* data compaction mode */
5412         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
5413         offset += 2;
5414
5415         /* 2 reserved bytes */
5416         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5417         offset += 2;
5418
5419         /* data len low */
5420         datalen_low = tvb_get_letohs(tvb, offset);
5421         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
5422         offset += 2;
5423
5424         /* data offset */
5425         dataoffset=tvb_get_letohs(tvb, offset);
5426         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5427         offset += 2;
5428
5429         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5430         /* data length high */
5431         datalen_high = tvb_get_letohs(tvb, offset);
5432         proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
5433         offset += 2;
5434
5435         datalen=datalen_high;
5436         datalen=(datalen<<16)|datalen_low;
5437
5438
5439         if (check_col(pinfo->cinfo, COL_INFO))
5440                 col_append_fstr(pinfo->cinfo, COL_INFO,
5441                                 ", %u byte%s", datalen,
5442                                 (datalen == 1) ? "" : "s");
5443
5444
5445         /* 8 reserved bytes */
5446         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
5447         offset += 8;
5448
5449         BYTE_COUNT;
5450
5451         /* file data, might be DCERPC on a pipe */
5452         if(bc){
5453                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5454                     top_tree, offset, bc, datalen, 0, fid);
5455                 bc = 0;
5456         }
5457
5458         END_OF_SMB
5459
5460         /* call AndXCommand (if there are any) */
5461         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5462
5463         return offset;
5464 }
5465
5466 static int
5467 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5468 {
5469         guint32 ofs=0;
5470         guint8  wc, cmd=0xff;
5471         guint16 andxoffset=0, bc, dataoffset=0, datalen_low, datalen_high;
5472         guint32 datalen=0;
5473         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5474         unsigned int fid=0;
5475         guint16 mode = 0;
5476
5477         WORD_COUNT;
5478
5479         /* next smb command */
5480         cmd = tvb_get_guint8(tvb, offset);
5481         if(cmd!=0xff){
5482                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5483         } else {
5484                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5485         }
5486         offset += 1;
5487
5488         /* reserved byte */
5489         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5490         offset += 1;
5491
5492         /* andxoffset */
5493         andxoffset = tvb_get_letohs(tvb, offset);
5494         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5495         offset += 2;
5496
5497         /* fid */
5498         fid = tvb_get_letohs(tvb, offset);
5499         add_fid(tvb, pinfo, tree, offset, 2, fid);
5500         offset += 2;
5501         if (!pinfo->fd->flags.visited) {
5502                 /* remember the FID for the processing of the response */
5503                 si->sip->extra_info=(void *)fid;
5504         }
5505
5506         /* offset */
5507         ofs = tvb_get_letohl(tvb, offset);
5508         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5509         offset += 4;
5510
5511         /* reserved */
5512         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5513         offset += 4;
5514
5515         /* mode */
5516         mode = tvb_get_letohs(tvb, offset);
5517         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
5518
5519         /* remaining */
5520         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5521         offset += 2;
5522
5523         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5524         /* data length high */
5525         datalen_high = tvb_get_letohs(tvb, offset);
5526         proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
5527         offset += 2;
5528
5529         /* data len low */
5530         datalen_low = tvb_get_letohs(tvb, offset);
5531         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
5532         offset += 2;
5533
5534         datalen=datalen_high;
5535         datalen=(datalen<<16)|datalen_low;
5536
5537         /* data offset */
5538         dataoffset=tvb_get_letohs(tvb, offset);
5539         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5540         offset += 2;
5541
5542         /* FIXME: handle Large (48-bit) byte/offset to COL_INFO */
5543         if (check_col(pinfo->cinfo, COL_INFO))
5544                 col_append_fstr(pinfo->cinfo, COL_INFO,
5545                                 ", %u byte%s at offset %u", datalen,
5546                                 (datalen == 1) ? "" : "s", ofs);
5547
5548         if(wc==14){
5549                 /* high offset */
5550                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5551                 offset += 4;
5552         }
5553
5554         BYTE_COUNT;
5555
5556         /* if both the MessageStart and the  WriteRawNamedPipe flags are set
5557            the first two bytes of the payload is the length of the data
5558            also this tells us that this is indeed the IPC$ share
5559            (if we didnt already know that 
5560         */
5561         if((mode&(WRITE_MODE_MESSAGE_START|WRITE_MODE_RAW))==(WRITE_MODE_MESSAGE_START|WRITE_MODE_RAW)){
5562                 proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, TRUE);
5563                 offset += 2;
5564                 dataoffset += 2;
5565                 bc -= 2;
5566                 datalen -= 2;
5567                 if(si->sip){
5568                         si->sip->flags|=SMB_SIF_TID_IS_IPC;
5569                 }
5570         }
5571
5572         /* file data, might be DCERPC on a pipe */
5573         if (bc != 0) {
5574                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5575                     top_tree, offset, bc, datalen, 0, fid);
5576                 bc = 0;
5577         }
5578
5579         END_OF_SMB
5580
5581         /* call AndXCommand (if there are any) */
5582         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5583
5584         return offset;
5585 }
5586
5587 static int
5588 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5589 {
5590         guint8  wc, cmd=0xff;
5591         guint16 andxoffset=0, bc, count_low, count_high;
5592         guint32 count=0;
5593         smb_info_t *si;
5594
5595         WORD_COUNT;
5596
5597         /* next smb command */
5598         cmd = tvb_get_guint8(tvb, offset);
5599         if(cmd!=0xff){
5600                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5601         } else {
5602                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5603         }
5604         offset += 1;
5605
5606         /* reserved byte */
5607         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5608         offset += 1;
5609
5610         /* andxoffset */
5611         andxoffset = tvb_get_letohs(tvb, offset);
5612         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5613         offset += 2;
5614
5615         /* If we have seen the request, then print which FID this refers to */
5616         si = (smb_info_t *)pinfo->private_data;
5617         /* first check if we have seen the request */
5618         if(si->sip != NULL && si->sip->frame_req>0){
5619                 add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
5620         }
5621
5622         /* write count low */
5623         count_low = tvb_get_letohs(tvb, offset);
5624         proto_tree_add_uint(tree, hf_smb_count_low, tvb, offset, 2, count_low);
5625         offset += 2;
5626
5627         /* remaining */
5628         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5629         offset += 2;
5630
5631         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5632         /* write count high */
5633         count_high = tvb_get_letohs(tvb, offset);
5634         proto_tree_add_uint(tree, hf_smb_count_high, tvb, offset, 2, count_high);
5635         offset += 2;
5636
5637         count=count_high;
5638         count=(count<<16)|count_low;
5639
5640         if (check_col(pinfo->cinfo, COL_INFO))
5641                 col_append_fstr(pinfo->cinfo, COL_INFO,
5642                                 ", %u byte%s", count,
5643                                 (count == 1) ? "" : "s");
5644
5645         /* 2 reserved bytes */
5646         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5647         offset += 2;
5648
5649         BYTE_COUNT;
5650
5651         END_OF_SMB
5652
5653         /* call AndXCommand (if there are any) */
5654         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5655
5656         return offset;
5657 }
5658
5659
5660 static const true_false_string tfs_setup_action_guest = {
5661         "Logged in as GUEST",
5662         "Not logged in as GUEST"
5663 };
5664 static int
5665 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5666 {
5667         guint16 mask;
5668         proto_item *item = NULL;
5669         proto_tree *tree = NULL;
5670
5671         mask = tvb_get_letohs(tvb, offset);
5672
5673         if(parent_tree){
5674                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5675                         "Action: 0x%04x", mask);
5676                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
5677         }
5678
5679         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
5680                 tvb, offset, 2, mask);
5681
5682         offset += 2;
5683
5684         return offset;
5685 }
5686
5687
5688 static int
5689 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5690 {
5691         guint8  wc, cmd=0xff;
5692         guint16 bc;
5693         guint16 andxoffset=0;
5694         smb_info_t *si = pinfo->private_data;
5695         int an_len;
5696         const char *an;
5697         int dn_len;
5698         const char *dn;
5699         guint16 pwlen=0;
5700         guint16 sbloblen=0;
5701         guint16 apwlen=0, upwlen=0;
5702
5703         WORD_COUNT;
5704
5705         /* next smb command */
5706         cmd = tvb_get_guint8(tvb, offset);
5707         if(cmd!=0xff){
5708                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5709         } else {
5710                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5711         }
5712         offset += 1;
5713
5714         /* reserved byte */
5715         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5716         offset += 1;
5717
5718         /* andxoffset */
5719         andxoffset = tvb_get_letohs(tvb, offset);
5720         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5721         offset += 2;
5722
5723         /* Maximum Buffer Size */
5724         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
5725         offset += 2;
5726
5727         /* Maximum Multiplex Count */
5728         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
5729         offset += 2;
5730
5731         /* VC Number */
5732         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
5733         offset += 2;
5734
5735         /* session key */
5736         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
5737         offset += 4;
5738
5739         switch (wc) {
5740         case 10:
5741                 /* password length, ASCII*/
5742                 pwlen = tvb_get_letohs(tvb, offset);
5743                 proto_tree_add_uint(tree, hf_smb_password_len,
5744                         tvb, offset, 2, pwlen);
5745                 offset += 2;
5746
5747                 /* 4 reserved bytes */
5748                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5749                 offset += 4;
5750
5751                 break;
5752
5753         case 12:
5754                 /* security blob length */
5755                 sbloblen = tvb_get_letohs(tvb, offset);
5756                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5757                 offset += 2;
5758
5759                 /* 4 reserved bytes */
5760                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5761                 offset += 4;
5762
5763                 /* capabilities */
5764                 dissect_negprot_capabilities(tvb, tree, offset);
5765                 offset += 4;
5766
5767                 break;
5768
5769         case 13:
5770                 /* password length, ANSI*/
5771                 apwlen = tvb_get_letohs(tvb, offset);
5772                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
5773                         tvb, offset, 2, apwlen);
5774                 offset += 2;
5775
5776                 /* password length, Unicode*/
5777                 upwlen = tvb_get_letohs(tvb, offset);
5778                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
5779                         tvb, offset, 2, upwlen);
5780                 offset += 2;
5781
5782                 /* 4 reserved bytes */
5783                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5784                 offset += 4;
5785
5786                 /* capabilities */
5787                 dissect_negprot_capabilities(tvb, tree, offset);
5788                 offset += 4;
5789
5790                 break;
5791         }
5792
5793         BYTE_COUNT;
5794
5795         if (wc==12) {
5796                 proto_item *blob_item;
5797
5798                 /* security blob */
5799
5800                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
5801                                                 tvb, offset, sbloblen, TRUE);
5802
5803                 /* As an optimization, because Windows is perverse,
5804                    we check to see if NTLMSSP is the first part of the 
5805                    blob, and if so, call the NTLMSSP dissector,
5806                    otherwise we call the GSS-API dissector. This is because
5807                    Windows can request RAW NTLMSSP, but will happily handle
5808                    a client that wraps NTLMSSP in SPNEGO
5809                 */
5810
5811                 if(sbloblen){
5812                         tvbuff_t *blob_tvb;
5813                         proto_tree *blob_tree;
5814
5815                         blob_tree = proto_item_add_subtree(blob_item, 
5816                                                            ett_smb_secblob);
5817                         CHECK_BYTE_COUNT(sbloblen);
5818
5819                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
5820                                                   sbloblen);
5821
5822                         if (si && si->ct && si->ct->raw_ntlmssp && 
5823                             !strncmp("NTLMSSP", 
5824                                      tvb_get_ptr(tvb, offset, 7), 7)) {
5825                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
5826                                          blob_tree);
5827
5828                         }
5829                         else {
5830                           call_dissector(gssapi_handle, blob_tvb, 
5831                                          pinfo, blob_tree);
5832                         }
5833
5834                         COUNT_BYTES(sbloblen);
5835                 }
5836
5837                 /* OS */
5838                 an = get_unicode_or_ascii_string(tvb, &offset,
5839                         si->unicode, &an_len, FALSE, FALSE, &bc);
5840                 if (an == NULL)
5841                         goto endofcommand;
5842                 proto_tree_add_string(tree, hf_smb_os, tvb,
5843                         offset, an_len, an);
5844                 COUNT_BYTES(an_len);
5845
5846                 /* LANMAN */
5847                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5848                  * padding/null string/whatever in front of this. W2K doesn't
5849                  * appear to. I suspect that's a bug that got fixed; I also
5850                  * suspect that, in practice, nobody ever looks at that field
5851                  * because the bug didn't appear to get fixed until NT 5.0....
5852                  */
5853                 an = get_unicode_or_ascii_string(tvb, &offset,
5854                         si->unicode, &an_len, FALSE, FALSE, &bc);
5855                 if (an == NULL)
5856                         goto endofcommand;
5857                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5858                         offset, an_len, an);
5859                 COUNT_BYTES(an_len);
5860
5861                 /* Primary domain */
5862                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5863                  * byte in front of this, at least if all the strings are
5864                  * ASCII and the account name is empty. Another bug?
5865                  */
5866                 dn = get_unicode_or_ascii_string(tvb, &offset,
5867                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5868                 if (dn == NULL)
5869                         goto endofcommand;
5870                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5871                         offset, dn_len, dn);
5872                 COUNT_BYTES(dn_len);
5873         } else {
5874                 switch (wc) {
5875
5876                 case 10:
5877                         if(pwlen){
5878                                 /* password, ASCII */
5879                                 CHECK_BYTE_COUNT(pwlen);
5880                                 proto_tree_add_item(tree, hf_smb_password,
5881                                         tvb, offset, pwlen, TRUE);
5882                                 COUNT_BYTES(pwlen);
5883                         }
5884
5885                         break;
5886
5887                 case 13:
5888                         if(apwlen){
5889                                 /* password, ANSI */
5890                                 CHECK_BYTE_COUNT(apwlen);
5891                                 proto_tree_add_item(tree, hf_smb_ansi_password,
5892                                         tvb, offset, apwlen, TRUE);
5893                                 COUNT_BYTES(apwlen);
5894                         }
5895
5896                         if(upwlen){
5897                                 proto_item *item;
5898
5899                                 /* password, Unicode */
5900                                 CHECK_BYTE_COUNT(upwlen);
5901                                 item = proto_tree_add_item(tree, hf_smb_unicode_password,
5902                                         tvb, offset, upwlen, TRUE);
5903
5904                                 if (upwlen > 24) {
5905                                         proto_tree *subtree;
5906
5907                                         subtree = proto_item_add_subtree(item, ett_smb_unicode_password);
5908
5909                                         dissect_ntlmv2_response(
5910                                                 tvb, subtree, offset, upwlen);
5911                                 }
5912
5913                                 COUNT_BYTES(upwlen);
5914                         }
5915
5916                         break;
5917                 }
5918
5919                 /* Account Name */
5920                 an = get_unicode_or_ascii_string(tvb, &offset,
5921                         si->unicode, &an_len, FALSE, FALSE, &bc);
5922                 if (an == NULL)
5923                         goto endofcommand;
5924                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
5925                         an);
5926                 COUNT_BYTES(an_len);
5927
5928                 /* Primary domain */
5929                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5930                  * byte in front of this, at least if all the strings are
5931                  * ASCII and the account name is empty. Another bug?
5932                  */
5933                 dn = get_unicode_or_ascii_string(tvb, &offset,
5934                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5935                 if (dn == NULL)
5936                         goto endofcommand;
5937                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5938                         offset, dn_len, dn);
5939                 COUNT_BYTES(dn_len);
5940
5941                 if (check_col(pinfo->cinfo, COL_INFO)) {
5942                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
5943
5944                         if (!dn[0] && !an[0])
5945                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5946                                                 "anonymous");
5947                         else
5948                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5949                                                 "%s\\%s", dn,an);
5950                 }
5951
5952                 /* OS */
5953                 an = get_unicode_or_ascii_string(tvb, &offset,
5954                         si->unicode, &an_len, FALSE, FALSE, &bc);
5955                 if (an == NULL)
5956                         goto endofcommand;
5957                 proto_tree_add_string(tree, hf_smb_os, tvb,
5958                         offset, an_len, an);
5959                 COUNT_BYTES(an_len);
5960
5961                 /* LANMAN */
5962                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5963                  * padding/null string/whatever in front of this. W2K doesn't
5964                  * appear to. I suspect that's a bug that got fixed; I also
5965                  * suspect that, in practice, nobody ever looks at that field
5966                  * because the bug didn't appear to get fixed until NT 5.0....
5967                  */
5968                 an = get_unicode_or_ascii_string(tvb, &offset,
5969                         si->unicode, &an_len, FALSE, FALSE, &bc);
5970                 if (an == NULL)
5971                         goto endofcommand;
5972                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5973                         offset, an_len, an);
5974                 COUNT_BYTES(an_len);
5975         }
5976
5977         END_OF_SMB
5978
5979         /* call AndXCommand (if there are any) */
5980         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5981
5982         return offset;
5983 }
5984
5985 static int
5986 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5987 {
5988         guint8  wc, cmd=0xff;
5989         guint16 andxoffset=0, bc;
5990         guint16 sbloblen=0;
5991         smb_info_t *si = pinfo->private_data;
5992         int an_len;
5993         const char *an;
5994
5995         WORD_COUNT;
5996
5997         /* next smb command */
5998         cmd = tvb_get_guint8(tvb, offset);
5999         if(cmd!=0xff){
6000                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6001         } else {
6002                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6003         }
6004         offset += 1;
6005
6006         /* reserved byte */
6007         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6008         offset += 1;
6009
6010         /* andxoffset */
6011         andxoffset = tvb_get_letohs(tvb, offset);
6012         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6013         offset += 2;
6014
6015         /* flags */
6016         offset = dissect_setup_action(tvb, tree, offset);
6017
6018         if(wc==4){
6019                 /* security blob length */
6020                 sbloblen = tvb_get_letohs(tvb, offset);
6021                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
6022                 offset += 2;
6023         }
6024
6025         BYTE_COUNT;
6026
6027         if(wc==4) {
6028                 proto_item *blob_item;
6029
6030                 /* security blob */
6031
6032                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
6033                                                 tvb, offset, sbloblen, TRUE);
6034
6035                 if(sbloblen){
6036                         tvbuff_t *blob_tvb;
6037                         proto_tree *blob_tree;
6038
6039                         blob_tree = proto_item_add_subtree(blob_item, 
6040                                                            ett_smb_secblob);
6041                         CHECK_BYTE_COUNT(sbloblen);
6042
6043                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
6044                                                     sbloblen);
6045
6046                         if (si && si->ct && si->ct->raw_ntlmssp && 
6047                             !strncmp("NTLMSSP", 
6048                                      tvb_get_ptr(tvb, offset, 7), 7)) {
6049                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
6050                                          blob_tree);
6051
6052                         }
6053                         else {
6054                           call_dissector(gssapi_handle, blob_tvb, pinfo, 
6055                                          blob_tree);
6056
6057                         }
6058
6059                         COUNT_BYTES(sbloblen);
6060                 }
6061         }
6062
6063         /* OS */
6064         an = get_unicode_or_ascii_string(tvb, &offset,
6065                 si->unicode, &an_len, FALSE, FALSE, &bc);
6066         if (an == NULL)
6067                 goto endofcommand;
6068         proto_tree_add_string(tree, hf_smb_os, tvb,
6069                 offset, an_len, an);
6070         COUNT_BYTES(an_len);
6071
6072         /* LANMAN */
6073         an = get_unicode_or_ascii_string(tvb, &offset,
6074                 si->unicode, &an_len, FALSE, FALSE, &bc);
6075         if (an == NULL)
6076                 goto endofcommand;
6077         proto_tree_add_string(tree, hf_smb_lanman, tvb,
6078                 offset, an_len, an);
6079         COUNT_BYTES(an_len);
6080
6081         if(wc==3) {
6082                 /* Primary domain */
6083                 an = get_unicode_or_ascii_string(tvb, &offset,
6084                         si->unicode, &an_len, FALSE, FALSE, &bc);
6085                 if (an == NULL)
6086                         goto endofcommand;
6087                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
6088                         offset, an_len, an);
6089                 COUNT_BYTES(an_len);
6090         }
6091
6092         END_OF_SMB
6093
6094         /* call AndXCommand (if there are any) */
6095         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6096
6097         return offset;
6098 }
6099
6100
6101 static int
6102 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6103 {
6104         guint8  wc, cmd=0xff;
6105         guint16 andxoffset=0;
6106         guint16 bc;
6107
6108         WORD_COUNT;
6109
6110         /* next smb command */
6111         cmd = tvb_get_guint8(tvb, offset);
6112         if(cmd!=0xff){
6113                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6114         } else {
6115                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6116         }
6117         offset += 1;
6118
6119         /* reserved byte */
6120         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6121         offset += 1;
6122
6123         /* andxoffset */
6124         andxoffset = tvb_get_letohs(tvb, offset);
6125         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6126         offset += 2;
6127
6128         BYTE_COUNT;
6129
6130         END_OF_SMB
6131
6132         /* call AndXCommand (if there are any) */
6133         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6134
6135         return offset;
6136 }
6137
6138
6139 static const true_false_string tfs_connect_support_search = {
6140         "Exclusive search bits supported",
6141         "Exclusive search bits not supported"
6142 };
6143 static const true_false_string tfs_connect_support_in_dfs = {
6144         "Share is in Dfs",
6145         "Share isn't in Dfs"
6146 };
6147
6148 static int
6149 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6150 {
6151         guint16 mask;
6152         proto_item *item = NULL;
6153         proto_tree *tree = NULL;
6154
6155         mask = tvb_get_letohs(tvb, offset);
6156
6157         if(parent_tree){
6158                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6159                         "Optional Support: 0x%04x", mask);
6160                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
6161         }
6162
6163         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
6164                 tvb, offset, 2, mask);
6165         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
6166                 tvb, offset, 2, mask);
6167
6168         offset += 2;
6169
6170         return offset;
6171 }
6172
6173 static const true_false_string tfs_disconnect_tid = {
6174         "DISCONNECT TID",
6175         "Do NOT disconnect TID"
6176 };
6177
6178 static int
6179 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6180 {
6181         guint16 mask;
6182         proto_item *item = NULL;
6183         proto_tree *tree = NULL;
6184
6185         mask = tvb_get_letohs(tvb, offset);
6186
6187         if(parent_tree){
6188                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6189                         "Flags: 0x%04x", mask);
6190                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
6191         }
6192
6193         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
6194                 tvb, offset, 2, mask);
6195
6196         offset += 2;
6197
6198         return offset;
6199 }
6200
6201 static int
6202 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6203 {
6204         guint8  wc, cmd=0xff;
6205         guint16 bc;
6206         guint16 andxoffset=0, pwlen=0;
6207         smb_info_t *si = pinfo->private_data;
6208         int an_len;
6209         const char *an;
6210
6211         WORD_COUNT;
6212
6213         /* next smb command */
6214         cmd = tvb_get_guint8(tvb, offset);
6215         if(cmd!=0xff){
6216                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6217         } else {
6218                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6219         }
6220         offset += 1;
6221
6222         /* reserved byte */
6223         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6224         offset += 1;
6225
6226         /* andxoffset */
6227         andxoffset = tvb_get_letohs(tvb, offset);
6228         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6229         offset += 2;
6230
6231         /* flags */
6232         offset = dissect_connect_flags(tvb, tree, offset);
6233
6234         /* password length*/
6235         pwlen = tvb_get_letohs(tvb, offset);
6236         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
6237         offset += 2;
6238
6239         BYTE_COUNT;
6240
6241         /* password */
6242         CHECK_BYTE_COUNT(pwlen);
6243         proto_tree_add_item(tree, hf_smb_password,
6244                 tvb, offset, pwlen, TRUE);
6245         COUNT_BYTES(pwlen);
6246
6247         /* Path */
6248         an = get_unicode_or_ascii_string(tvb, &offset,
6249                 si->unicode, &an_len, FALSE, FALSE, &bc);
6250         if (an == NULL)
6251                 goto endofcommand;
6252         proto_tree_add_string(tree, hf_smb_path, tvb,
6253                 offset, an_len, an);
6254         COUNT_BYTES(an_len);
6255
6256         if (check_col(pinfo->cinfo, COL_INFO)) {
6257                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
6258         }
6259
6260         /*
6261          * NOTE: the Service string is always ASCII, even if the
6262          * "strings are Unicode" bit is set in the flags2 field
6263          * of the SMB.
6264          */
6265
6266         /* Service */
6267         /* XXX - what if this runs past bc? */
6268         an_len = tvb_strsize(tvb, offset);
6269         CHECK_BYTE_COUNT(an_len);
6270         an = tvb_get_ptr(tvb, offset, an_len);
6271         proto_tree_add_string(tree, hf_smb_service, tvb,
6272                 offset, an_len, an);
6273         COUNT_BYTES(an_len);
6274
6275         END_OF_SMB
6276
6277         /* call AndXCommand (if there are any) */
6278         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6279
6280         return offset;
6281 }
6282
6283
6284 static int
6285 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6286 {
6287         guint8  wc, wleft, cmd=0xff;
6288         guint16 andxoffset=0;
6289         guint16 bc;
6290         int an_len;
6291         const char *an;
6292         smb_info_t *si = pinfo->private_data;
6293
6294         WORD_COUNT;
6295
6296         wleft = wc;     /* this is at least 1 */
6297
6298         /* next smb command */
6299         cmd = tvb_get_guint8(tvb, offset);
6300         if(cmd!=0xff){
6301                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6302         } else {
6303                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6304         }
6305         offset += 1;
6306
6307         /* reserved byte */
6308         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6309         offset += 1;
6310
6311         wleft--;
6312         if (wleft == 0)
6313                 goto bytecount;
6314
6315         /* andxoffset */
6316         andxoffset = tvb_get_letohs(tvb, offset);
6317         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6318         offset += 2;
6319         wleft--;
6320         if (wleft == 0)
6321                 goto bytecount;
6322
6323         /* flags */
6324         offset = dissect_connect_support_bits(tvb, tree, offset);
6325         wleft--;
6326
6327         /* XXX - I've seen captures where this is 7, but I have no
6328            idea how to dissect it.  I'm guessing the third word
6329            contains connect support bits, which looks plausible
6330            from the values I've seen. */
6331
6332         while (wleft != 0) {
6333                 proto_tree_add_text(tree, tvb, offset, 2,
6334                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
6335                 offset += 2;
6336                 wleft--;
6337         }
6338
6339         BYTE_COUNT;
6340
6341         /*
6342          * NOTE: even though the SNIA CIFS spec doesn't say there's
6343          * a "Service" string if there's a word count of 2, the
6344          * document at
6345          *
6346          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
6347          *
6348          * (it's in an ugly format - text intended to be sent to a
6349          * printer, with backspaces and overstrikes used for boldfacing
6350          * and underlining; UNIX "col -b" can be used to strip the
6351          * overstrikes out) says there's a "Service" string there, and
6352          * some network traffic has it.
6353          */
6354
6355         /*
6356          * NOTE: the Service string is always ASCII, even if the
6357          * "strings are Unicode" bit is set in the flags2 field
6358          * of the SMB.
6359          */
6360
6361         /* Service */
6362         /* XXX - what if this runs past bc? */
6363         an_len = tvb_strsize(tvb, offset);
6364         CHECK_BYTE_COUNT(an_len);
6365         an = tvb_get_ptr(tvb, offset, an_len);
6366         proto_tree_add_string(tree, hf_smb_service, tvb,
6367                 offset, an_len, an);
6368         COUNT_BYTES(an_len);
6369
6370         /* Now when we know the service type, store it so that we know it for later commands down
6371            this tree */
6372         if(!pinfo->fd->flags.visited){
6373                 /* Remove any previous entry for this TID */
6374                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
6375                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
6376                 }
6377                 if(strcmp(an,"IPC") == 0){
6378                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
6379                 } else {
6380                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
6381                 }
6382         }
6383
6384
6385         if(wc==3){
6386                 if (bc != 0) {
6387                         /*
6388                          * Sometimes this isn't present.
6389                          */
6390
6391                         /* Native FS */
6392                         an = get_unicode_or_ascii_string(tvb, &offset,
6393                                 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
6394                                 &bc);
6395                         if (an == NULL)
6396                                 goto endofcommand;
6397                         proto_tree_add_string(tree, hf_smb_fs, tvb,
6398                                 offset, an_len, an);
6399                         COUNT_BYTES(an_len);
6400                 }
6401         }
6402
6403         END_OF_SMB
6404
6405         /* call AndXCommand (if there are any) */
6406         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6407
6408         return offset;
6409 }
6410
6411
6412
6413 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6414    NT Transaction command  begins here
6415    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
6416 #define NT_TRANS_CREATE         1
6417 #define NT_TRANS_IOCTL          2
6418 #define NT_TRANS_SSD            3
6419 #define NT_TRANS_NOTIFY         4
6420 #define NT_TRANS_RENAME         5
6421 #define NT_TRANS_QSD            6
6422 #define NT_TRANS_GET_USER_QUOTA 7
6423 #define NT_TRANS_SET_USER_QUOTA 8
6424 const value_string nt_cmd_vals[] = {
6425         {NT_TRANS_CREATE,               "NT CREATE"},
6426         {NT_TRANS_IOCTL,                "NT IOCTL"},
6427         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
6428         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
6429         {NT_TRANS_RENAME,               "NT RENAME"},
6430         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
6431         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
6432         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
6433         {0, NULL}
6434 };
6435
6436 static const value_string nt_ioctl_isfsctl_vals[] = {
6437         {0,     "Device IOCTL"},
6438         {1,     "FS control : FSCTL"},
6439         {0, NULL}
6440 };
6441
6442 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
6443 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
6444         "Apply the command to share root handle (MUST BE Dfs)",
6445         "Apply to this share",
6446 };
6447
6448 static const value_string nt_notify_action_vals[] = {
6449         {1,     "ADDED (object was added"},
6450         {2,     "REMOVED (object was removed)"},
6451         {3,     "MODIFIED (object was modified)"},
6452         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
6453         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
6454         {6,     "ADDED_STREAM (a stream was added)"},
6455         {7,     "REMOVED_STREAM (a stream was removed)"},
6456         {8,     "MODIFIED_STREAM (a stream was modified)"},
6457         {0, NULL}
6458 };
6459
6460 static const value_string watch_tree_vals[] = {
6461         {0,     "Current directory only"},
6462         {1,     "Subdirectories also"},
6463         {0, NULL}
6464 };
6465
6466 #define NT_NOTIFY_STREAM_WRITE  0x00000800
6467 #define NT_NOTIFY_STREAM_SIZE   0x00000400
6468 #define NT_NOTIFY_STREAM_NAME   0x00000200
6469 #define NT_NOTIFY_SECURITY      0x00000100
6470 #define NT_NOTIFY_EA            0x00000080
6471 #define NT_NOTIFY_CREATION      0x00000040
6472 #define NT_NOTIFY_LAST_ACCESS   0x00000020
6473 #define NT_NOTIFY_LAST_WRITE    0x00000010
6474 #define NT_NOTIFY_SIZE          0x00000008
6475 #define NT_NOTIFY_ATTRIBUTES    0x00000004
6476 #define NT_NOTIFY_DIR_NAME      0x00000002
6477 #define NT_NOTIFY_FILE_NAME     0x00000001
6478 static const true_false_string tfs_nt_notify_stream_write = {
6479         "Notify on changes to STREAM WRITE",
6480         "Do NOT notify on changes to stream write",
6481 };
6482 static const true_false_string tfs_nt_notify_stream_size = {
6483         "Notify on changes to STREAM SIZE",
6484         "Do NOT notify on changes to stream size",
6485 };
6486 static const true_false_string tfs_nt_notify_stream_name = {
6487         "Notify on changes to STREAM NAME",
6488         "Do NOT notify on changes to stream name",
6489 };
6490 static const true_false_string tfs_nt_notify_security = {
6491         "Notify on changes to SECURITY",
6492         "Do NOT notify on changes to security",
6493 };
6494 static const true_false_string tfs_nt_notify_ea = {
6495         "Notify on changes to EA",
6496         "Do NOT notify on changes to EA",
6497 };
6498 static const true_false_string tfs_nt_notify_creation = {
6499         "Notify on changes to CREATION TIME",
6500         "Do NOT notify on changes to creation time",
6501 };
6502 static const true_false_string tfs_nt_notify_last_access = {
6503         "Notify on changes to LAST ACCESS TIME",
6504         "Do NOT notify on changes to last access time",
6505 };
6506 static const true_false_string tfs_nt_notify_last_write = {
6507         "Notify on changes to LAST WRITE TIME",
6508         "Do NOT notify on changes to last write time",
6509 };
6510 static const true_false_string tfs_nt_notify_size = {
6511         "Notify on changes to SIZE",
6512         "Do NOT notify on changes to size",
6513 };
6514 static const true_false_string tfs_nt_notify_attributes = {
6515         "Notify on changes to ATTRIBUTES",
6516         "Do NOT notify on changes to attributes",
6517 };
6518 static const true_false_string tfs_nt_notify_dir_name = {
6519         "Notify on changes to DIR NAME",
6520         "Do NOT notify on changes to dir name",
6521 };
6522 static const true_false_string tfs_nt_notify_file_name = {
6523         "Notify on changes to FILE NAME",
6524         "Do NOT notify on changes to file name",
6525 };
6526
6527 static const value_string create_disposition_vals[] = {
6528         {0,     "Supersede (supersede existing file (if it exists))"},
6529         {1,     "Open (if file exists open it, else fail)"},
6530         {2,     "Create (if file exists fail, else create it)"},
6531         {3,     "Open If (if file exists open it, else create it)"},
6532         {4,     "Overwrite (if file exists overwrite, else fail)"},
6533         {5,     "Overwrite If (if file exists overwrite, else create it)"},
6534         {0, NULL}
6535 };
6536
6537 static const value_string impersonation_level_vals[] = {
6538         {0,     "Anonymous"},
6539         {1,     "Identification"},
6540         {2,     "Impersonation"},
6541         {3,     "Delegation"},
6542         {0, NULL}
6543 };
6544
6545 static const true_false_string tfs_nt_security_flags_context_tracking = {
6546         "Security tracking mode is DYNAMIC",
6547         "Security tracking mode is STATIC",
6548 };
6549
6550 static const true_false_string tfs_nt_security_flags_effective_only = {
6551         "ONLY ENABLED aspects of the client's security context are available",
6552         "ALL aspects of the client's security context are available",
6553 };
6554
6555 static const true_false_string tfs_nt_create_bits_oplock = {
6556         "Requesting OPLOCK",
6557         "Does NOT request oplock"
6558 };
6559
6560 static const true_false_string tfs_nt_create_bits_boplock = {
6561         "Requesting BATCH OPLOCK",
6562         "Does NOT request batch oplock"
6563 };
6564
6565 /*
6566  * XXX - must be a directory, and can be a file, or can be a directory,
6567  * and must be a file?
6568  */
6569 static const true_false_string tfs_nt_create_bits_dir = {
6570         "Target of open MUST be a DIRECTORY",
6571         "Target of open can be a file"
6572 };
6573
6574 static const true_false_string tfs_nt_create_bits_ext_resp = {
6575   "Extended responses required",
6576   "Extended responses NOT required"
6577 };
6578
6579 static const true_false_string tfs_nt_access_mask_generic_read = {
6580         "GENERIC READ is set",
6581         "Generic read is NOT set"
6582 };
6583 static const true_false_string tfs_nt_access_mask_generic_write = {
6584         "GENERIC WRITE is set",
6585         "Generic write is NOT set"
6586 };
6587 static const true_false_string tfs_nt_access_mask_generic_execute = {
6588         "GENERIC EXECUTE is set",
6589         "Generic execute is NOT set"
6590 };
6591 static const true_false_string tfs_nt_access_mask_generic_all = {
6592         "GENERIC ALL is set",
6593         "Generic all is NOT set"
6594 };
6595 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
6596         "MAXIMUM ALLOWED is set",
6597         "Maximum allowed is NOT set"
6598 };
6599 static const true_false_string tfs_nt_access_mask_system_security = {
6600         "SYSTEM SECURITY is set",
6601         "System security is NOT set"
6602 };
6603 static const true_false_string tfs_nt_access_mask_synchronize = {
6604         "Can wait on handle to SYNCHRONIZE on completion of I/O",
6605         "Can NOT wait on handle to synchronize on completion of I/O"
6606 };
6607 static const true_false_string tfs_nt_access_mask_write_owner = {
6608         "Can WRITE OWNER (take ownership)",
6609         "Can NOT write owner (take ownership)"
6610 };
6611 static const true_false_string tfs_nt_access_mask_write_dac = {
6612         "OWNER may WRITE the DAC",
6613         "Owner may NOT write to the DAC"
6614 };
6615 static const true_false_string tfs_nt_access_mask_read_control = {
6616         "READ ACCESS to owner, group and ACL of the SID",
6617         "Read access is NOT granted to owner, group and ACL of the SID"
6618 };
6619 static const true_false_string tfs_nt_access_mask_delete = {
6620         "DELETE access",
6621         "NO delete access"
6622 };
6623 static const true_false_string tfs_nt_access_mask_write_attributes = {
6624         "WRITE ATTRIBUTES access",
6625         "NO write attributes access"
6626 };
6627 static const true_false_string tfs_nt_access_mask_read_attributes = {
6628         "READ ATTRIBUTES access",
6629         "NO read attributes access"
6630 };
6631 static const true_false_string tfs_nt_access_mask_delete_child = {
6632         "DELETE CHILD access",
6633         "NO delete child access"
6634 };
6635 static const true_false_string tfs_nt_access_mask_execute = {
6636         "EXECUTE access",
6637         "NO execute access"
6638 };
6639 static const true_false_string tfs_nt_access_mask_write_ea = {
6640         "WRITE EXTENDED ATTRIBUTES access",
6641         "NO write extended attributes access"
6642 };
6643 static const true_false_string tfs_nt_access_mask_read_ea = {
6644         "READ EXTENDED ATTRIBUTES access",
6645         "NO read extended attributes access"
6646 };
6647 static const true_false_string tfs_nt_access_mask_append = {
6648         "APPEND access",
6649         "NO append access"
6650 };
6651 static const true_false_string tfs_nt_access_mask_write = {
6652         "WRITE access",
6653         "NO write access"
6654 };
6655 static const true_false_string tfs_nt_access_mask_read = {
6656         "READ access",
6657         "NO read access"
6658 };
6659
6660 static const true_false_string tfs_nt_share_access_delete = {
6661         "Object can be shared for DELETE",
6662         "Object can NOT be shared for delete"
6663 };
6664 static const true_false_string tfs_nt_share_access_write = {
6665         "Object can be shared for WRITE",
6666         "Object can NOT be shared for write"
6667 };
6668 static const true_false_string tfs_nt_share_access_read = {
6669         "Object can be shared for READ",
6670         "Object can NOT be shared for read"
6671 };
6672
6673 static const value_string oplock_level_vals[] = {
6674         {0,     "No oplock granted"},
6675         {1,     "Exclusive oplock granted"},
6676         {2,     "Batch oplock granted"},
6677         {3,     "Level II oplock granted"},
6678         {0, NULL}
6679 };
6680
6681 static const value_string device_type_vals[] = {
6682         {0x00000001,    "Beep"},
6683         {0x00000002,    "CDROM"},
6684         {0x00000003,    "CDROM Filesystem"},
6685         {0x00000004,    "Controller"},
6686         {0x00000005,    "Datalink"},
6687         {0x00000006,    "Dfs"},
6688         {0x00000007,    "Disk"},
6689         {0x00000008,    "Disk Filesystem"},
6690         {0x00000009,    "Filesystem"},
6691         {0x0000000a,    "Inport Port"},
6692         {0x0000000b,    "Keyboard"},
6693         {0x0000000c,    "Mailslot"},
6694         {0x0000000d,    "MIDI-In"},
6695         {0x0000000e,    "MIDI-Out"},
6696         {0x0000000f,    "Mouse"},
6697         {0x00000010,    "Multi UNC Provider"},
6698         {0x00000011,    "Named Pipe"},
6699         {0x00000012,    "Network"},
6700         {0x00000013,    "Network Browser"},
6701         {0x00000014,    "Network Filesystem"},
6702         {0x00000015,    "NULL"},
6703         {0x00000016,    "Parallel Port"},
6704         {0x00000017,    "Physical card"},
6705         {0x00000018,    "Printer"},
6706         {0x00000019,    "Scanner"},
6707         {0x0000001a,    "Serial Mouse port"},
6708         {0x0000001b,    "Serial port"},
6709         {0x0000001c,    "Screen"},
6710         {0x0000001d,    "Sound"},
6711         {0x0000001e,    "Streams"},
6712         {0x0000001f,    "Tape"},
6713         {0x00000020,    "Tape Filesystem"},
6714         {0x00000021,    "Transport"},
6715         {0x00000022,    "Unknown"},
6716         {0x00000023,    "Video"},
6717         {0x00000024,    "Virtual Disk"},
6718         {0x00000025,    "WAVE-In"},
6719         {0x00000026,    "WAVE-Out"},
6720         {0x00000027,    "8042 Port"},
6721         {0x00000028,    "Network Redirector"},
6722         {0x00000029,    "Battery"},
6723         {0x0000002a,    "Bus Extender"},
6724         {0x0000002b,    "Modem"},
6725         {0x0000002c,    "VDM"},
6726         {0,     NULL}
6727 };
6728
6729 static const value_string is_directory_vals[] = {
6730         {0,     "This is NOT a directory"},
6731         {1,     "This is a DIRECTORY"},
6732         {0, NULL}
6733 };
6734
6735 typedef struct _nt_trans_data {
6736         int subcmd;
6737         guint32 sd_len;
6738         guint32 ea_len;
6739 } nt_trans_data;
6740
6741
6742
6743 static int
6744 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6745 {
6746         guint8 mask;
6747         proto_item *item = NULL;
6748         proto_tree *tree = NULL;
6749
6750         mask = tvb_get_guint8(tvb, offset);
6751
6752         if(parent_tree){
6753                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6754                         "Security Flags: 0x%02x", mask);
6755                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
6756         }
6757
6758         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
6759                 tvb, offset, 1, mask);
6760         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
6761                 tvb, offset, 1, mask);
6762
6763         offset += 1;
6764
6765         return offset;
6766 }
6767
6768 static int
6769 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6770 {
6771         guint32 mask;
6772         proto_item *item = NULL;
6773         proto_tree *tree = NULL;
6774
6775         mask = tvb_get_letohl(tvb, offset);
6776
6777         if(parent_tree){
6778                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6779                         "Share Access: 0x%08x", mask);
6780                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
6781         }
6782
6783         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
6784                 tvb, offset, 4, mask);
6785         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
6786                 tvb, offset, 4, mask);
6787         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
6788                 tvb, offset, 4, mask);
6789
6790         offset += 4;
6791
6792         return offset;
6793 }
6794
6795 /* FIXME: need to call dissect_nt_access_mask() instead */
6796
6797 static int
6798 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6799 {
6800         guint32 mask;
6801         proto_item *item = NULL;
6802         proto_tree *tree = NULL;
6803
6804         mask = tvb_get_letohl(tvb, offset);
6805
6806         if(parent_tree){
6807                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6808                         "Access Mask: 0x%08x", mask);
6809                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
6810         }
6811
6812         /*
6813          * Some of these bits come from
6814          *
6815          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6816          *
6817          * and others come from the section on ZwOpenFile in "Windows(R)
6818          * NT(R)/2000 Native API Reference".
6819          */
6820         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
6821                 tvb, offset, 4, mask);
6822         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
6823                 tvb, offset, 4, mask);
6824         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
6825                 tvb, offset, 4, mask);
6826         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
6827                 tvb, offset, 4, mask);
6828         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
6829                 tvb, offset, 4, mask);
6830         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
6831                 tvb, offset, 4, mask);
6832         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
6833                 tvb, offset, 4, mask);
6834         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
6835                 tvb, offset, 4, mask);
6836         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
6837                 tvb, offset, 4, mask);
6838         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
6839                 tvb, offset, 4, mask);
6840         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
6841                 tvb, offset, 4, mask);
6842         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
6843                 tvb, offset, 4, mask);
6844         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
6845                 tvb, offset, 4, mask);
6846         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
6847                 tvb, offset, 4, mask);
6848         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
6849                 tvb, offset, 4, mask);
6850         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
6851                 tvb, offset, 4, mask);
6852         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
6853                 tvb, offset, 4, mask);
6854         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
6855                 tvb, offset, 4, mask);
6856         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
6857                 tvb, offset, 4, mask);
6858         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
6859                 tvb, offset, 4, mask);
6860
6861         offset += 4;
6862
6863         return offset;
6864 }
6865
6866 static int
6867 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6868 {
6869         guint32 mask;
6870         proto_item *item = NULL;
6871         proto_tree *tree = NULL;
6872
6873         mask = tvb_get_letohl(tvb, offset);
6874
6875         if(parent_tree){
6876                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6877                         "Create Flags: 0x%08x", mask);
6878                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
6879         }
6880
6881         /*
6882          * XXX - it's 0x00000016 in at least one capture, but
6883          * Network Monitor doesn't say what the 0x00000010 bit is.
6884          * Does the Win32 API documentation, or NT Native API book,
6885          * suggest anything?
6886          *
6887          * That is the extended response desired bit ... RJS, from Samba
6888          * Well, maybe. Samba thinks it is, and uses it to encode
6889          * OpLock granted as the high order bit of the Action field
6890          * in the response. However, Windows does not do that. Or at least
6891          * Win2K doesn't.
6892          */
6893         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
6894                                tvb, offset, 4, mask);
6895         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
6896                 tvb, offset, 4, mask);
6897         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
6898                 tvb, offset, 4, mask);
6899         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
6900                 tvb, offset, 4, mask);
6901
6902         offset += 4;
6903
6904         return offset;
6905 }
6906
6907 /*
6908  * XXX - there are some more flags in the description of "ZwOpenFile()"
6909  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
6910  * the wire as well?  (The spec at
6911  *
6912  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6913  *
6914  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
6915  * via the SMB protocol.  The NT redirector should convert this option
6916  * to FILE_WRITE_THROUGH."
6917  *
6918  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
6919  * values one would infer from their position in the list of flags for
6920  * "ZwOpenFile()".  Most of the others probably have those values
6921  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
6922  * which might go over the wire (for the benefit of backup/restore software).
6923  */
6924 static const true_false_string tfs_nt_create_options_directory = {
6925         "File being created/opened must be a directory",
6926         "File being created/opened must not be a directory"
6927 };
6928 static const true_false_string tfs_nt_create_options_write_through = {
6929         "Writes should flush buffered data before completing",
6930         "Writes need not flush buffered data before completing"
6931 };
6932 static const true_false_string tfs_nt_create_options_sequential_only = {
6933         "The file will only be accessed sequentially",
6934         "The file might not only be accessed sequentially"
6935 };
6936 static const true_false_string tfs_nt_create_options_sync_io_alert = {
6937         "All operations SYNCHRONOUS, waits subject to termination from alert",
6938         "Operations NOT necessarily synchronous"
6939 };
6940 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
6941         "All operations SYNCHRONOUS, waits not subject to alert",
6942         "Operations NOT necessarily synchronous"
6943 };
6944 static const true_false_string tfs_nt_create_options_non_directory = {
6945         "File being created/opened must not be a directory",
6946         "File being created/opened must be a directory"
6947 };
6948 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
6949         "The client does not understand extended attributes",
6950         "The client understands extended attributes"
6951 };
6952 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
6953         "The client understands only 8.3 file names",
6954         "The client understands long file names"
6955 };
6956 static const true_false_string tfs_nt_create_options_random_access = {
6957         "The file will be accessed randomly",
6958         "The file will not be accessed randomly"
6959 };
6960 static const true_false_string tfs_nt_create_options_delete_on_close = {
6961         "The file should be deleted when it is closed",
6962         "The file should not be deleted when it is closed"
6963 };
6964
6965 static int
6966 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6967 {
6968         guint32 mask;
6969         proto_item *item = NULL;
6970         proto_tree *tree = NULL;
6971
6972         mask = tvb_get_letohl(tvb, offset);
6973
6974         if(parent_tree){
6975                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6976                         "Create Options: 0x%08x", mask);
6977                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
6978         }
6979
6980         /*
6981          * From
6982          *
6983          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6984          */
6985         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
6986                 tvb, offset, 4, mask);
6987         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
6988                 tvb, offset, 4, mask);
6989         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
6990                 tvb, offset, 4, mask);
6991         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
6992                 tvb, offset, 4, mask);
6993         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
6994                 tvb, offset, 4, mask);
6995         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
6996                 tvb, offset, 4, mask);
6997         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
6998                 tvb, offset, 4, mask);
6999         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
7000                 tvb, offset, 4, mask);
7001         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
7002                 tvb, offset, 4, mask);
7003         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
7004                 tvb, offset, 4, mask);
7005
7006         offset += 4;
7007
7008         return offset;
7009 }
7010
7011 static int
7012 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7013 {
7014         guint32 mask;
7015         proto_item *item = NULL;
7016         proto_tree *tree = NULL;
7017
7018         mask = tvb_get_letohl(tvb, offset);
7019
7020         if(parent_tree){
7021                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7022                         "Completion Filter: 0x%08x", mask);
7023                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
7024         }
7025
7026         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
7027                 tvb, offset, 4, mask);
7028         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
7029                 tvb, offset, 4, mask);
7030         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
7031                 tvb, offset, 4, mask);
7032         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
7033                 tvb, offset, 4, mask);
7034         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
7035                 tvb, offset, 4, mask);
7036         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
7037                 tvb, offset, 4, mask);
7038         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
7039                 tvb, offset, 4, mask);
7040         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
7041                 tvb, offset, 4, mask);
7042         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
7043                 tvb, offset, 4, mask);
7044         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
7045                 tvb, offset, 4, mask);
7046         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
7047                 tvb, offset, 4, mask);
7048         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
7049                 tvb, offset, 4, mask);
7050
7051         offset += 4;
7052         return offset;
7053 }
7054
7055 static int
7056 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7057 {
7058         guint8 mask;
7059         proto_item *item = NULL;
7060         proto_tree *tree = NULL;
7061
7062         mask = tvb_get_guint8(tvb, offset);
7063
7064         if(parent_tree){
7065                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7066                         "Completion Filter: 0x%02x", mask);
7067                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
7068         }
7069
7070         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
7071                 tvb, offset, 1, mask);
7072
7073         offset += 1;
7074         return offset;
7075 }
7076
7077 /*
7078  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
7079  * Native API Reference".
7080  */
7081 static const true_false_string tfs_nt_qsd_owner = {
7082         "Requesting OWNER security information",
7083         "NOT requesting owner security information",
7084 };
7085
7086 static const true_false_string tfs_nt_qsd_group = {
7087         "Requesting GROUP security information",
7088         "NOT requesting group security information",
7089 };
7090
7091 static const true_false_string tfs_nt_qsd_dacl = {
7092         "Requesting DACL security information",
7093         "NOT requesting DACL security information",
7094 };
7095
7096 static const true_false_string tfs_nt_qsd_sacl = {
7097         "Requesting SACL security information",
7098         "NOT requesting SACL security information",
7099 };
7100
7101 #define NT_QSD_OWNER    0x00000001
7102 #define NT_QSD_GROUP    0x00000002
7103 #define NT_QSD_DACL     0x00000004
7104 #define NT_QSD_SACL     0x00000008
7105
7106 static int
7107 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7108 {
7109         guint32 mask;
7110         proto_item *item = NULL;
7111         proto_tree *tree = NULL;
7112
7113         mask = tvb_get_letohl(tvb, offset);
7114
7115         if(parent_tree){
7116                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7117                         "Security Information: 0x%08x", mask);
7118                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
7119         }
7120
7121         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
7122                 tvb, offset, 4, mask);
7123         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
7124                 tvb, offset, 4, mask);
7125         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
7126                 tvb, offset, 4, mask);
7127         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
7128                 tvb, offset, 4, mask);
7129
7130         offset += 4;
7131
7132         return offset;
7133 }
7134
7135 static void
7136 free_g_string(void *arg)
7137 {
7138         g_string_free(arg, TRUE);
7139 }
7140
7141 /* Dissect a NT SID.  Label it with 'name' and return a string version of
7142    the SID in the 'sid_str' parameter which must be freed by the caller.
7143    hf_sid can be -1 if the caller doesnt care what name is used and then 
7144    "smb.sid" will be the default instead. If the caller wants a more
7145    appropriate hf field, it will just pass a FT_STRING hf field here
7146 */
7147
7148 int
7149 dissect_nt_sid(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name,
7150                char **sid_str, int hf_sid)
7151 {
7152         proto_item *item = NULL;
7153         proto_tree *tree = NULL;
7154         int old_offset = offset, sa_offset = offset;
7155         gboolean rid_present;
7156         guint rid=0;
7157         int rid_offset=0;
7158         guint8 revision;
7159         int rev_offset;
7160         guint8 num_auth;
7161         int na_offset;
7162         guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
7163         int i;
7164         GString *gstr;
7165         char sid_string[245];
7166         char *sid_name;
7167
7168         if(hf_sid==-1){
7169                 hf_sid=hf_smb_sid;
7170         }
7171
7172         /* revision of sid */
7173         revision = tvb_get_guint8(tvb, offset);
7174         rev_offset = offset;
7175         offset += 1;
7176
7177         switch(revision){
7178         case 1:
7179         case 2:  /* Not sure what the different revision numbers mean */
7180           /* number of authorities*/
7181           num_auth = tvb_get_guint8(tvb, offset);
7182           na_offset = offset;
7183           offset += 1;
7184
7185           /* XXX perhaps we should have these thing searchable?
7186              a new FT_xxx thingie? SMB is quite common!*/
7187           /* identifier authorities */
7188
7189           for(i=0;i<6;i++){
7190             auth = (auth << 8) + tvb_get_guint8(tvb, offset);
7191
7192             offset++;
7193           }
7194
7195           sa_offset = offset;
7196
7197           gstr = g_string_new("");
7198
7199           CLEANUP_PUSH(free_g_string, gstr);
7200
7201           /* sub authorities, leave RID to last */
7202           for(i=0; i < (num_auth > 4?(num_auth - 1):num_auth); i++){
7203             /*
7204              * XXX should not be letohl but native byteorder according to
7205              * Samba header files.
7206              *
7207              * However, considering that there were never any NT ports
7208              * to big-endian platforms (PowerPC and MIPS ran little-endian,
7209              * and IA-64 runs little-endian, as does x86-64), we can (?)
7210              * assume that non le byte encodings will be "uncommon"?
7211              */
7212              g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"),
7213                   tvb_get_letohl(tvb, offset));
7214              offset+=4;
7215           }
7216
7217
7218           if (num_auth > 4) {
7219             rid = tvb_get_letohl(tvb, offset);
7220             rid_present=TRUE;
7221             rid_offset=offset;
7222             offset+=4;
7223             sprintf(sid_string, "S-1-%u-%s-%u", auth, gstr->str, rid);
7224           } else {
7225             rid_present=FALSE;
7226             sprintf(sid_string, "S-1-%u-%s", auth, gstr->str);
7227           }
7228
7229           sid_name=NULL;
7230           if(sid_name_snooping){
7231             sid_name=find_sid_name(sid_string);
7232           }
7233
7234           if(parent_tree){
7235             if(sid_name){
7236               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);
7237             } else {
7238               item = proto_tree_add_string_format(parent_tree, hf_sid, tvb, old_offset, offset-old_offset, sid_string, "%s: %s", name, sid_string);
7239             }
7240             tree = proto_item_add_subtree(item, ett_smb_sid);
7241           }
7242
7243           proto_tree_add_item(tree, hf_smb_sid_revision, tvb, rev_offset, 1, TRUE);
7244           proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, na_offset, 1, TRUE);
7245           proto_tree_add_text(tree, tvb, na_offset+1, 6, "Authority: %u", auth);
7246           proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
7247
7248           if(rid_present){
7249             proto_tree_add_text(tree, tvb, rid_offset, 4, "RID: %u", rid);
7250           }
7251
7252           if(sid_str){
7253             if(sid_name){
7254               *sid_str = g_strdup_printf("%s (%s)", sid_string, sid_name);
7255             } else {
7256               *sid_str = g_strdup(sid_string);
7257             }
7258           }
7259
7260           CLEANUP_CALL_AND_POP;
7261         }
7262
7263
7264         return offset;
7265 }
7266
7267
7268 static const value_string ace_type_vals[] = {
7269   { 0, "Access Allowed"},
7270   { 1, "Access Denied"},
7271   { 2, "System Audit"},
7272   { 3, "System Alarm"},
7273   { 0, NULL}
7274 };
7275 static const true_false_string tfs_ace_flags_object_inherit = {
7276   "Subordinate files will inherit this ACE",
7277   "Subordinate files will not inherit this ACE"
7278 };
7279 static const true_false_string tfs_ace_flags_container_inherit = {
7280   "Subordinate containers will inherit this ACE",
7281   "Subordinate containers will not inherit this ACE"
7282 };
7283 static const true_false_string tfs_ace_flags_non_propagate_inherit = {
7284   "Subordinate object will not propagate the inherited ACE further",
7285   "Subordinate object will propagate the inherited ACE further"
7286 };
7287 static const true_false_string tfs_ace_flags_inherit_only = {
7288   "This ACE does not apply to the current object",
7289   "This ACE applies to the current object"
7290 };
7291 static const true_false_string tfs_ace_flags_inherited_ace = {
7292   "This ACE was inherited from its parent object",
7293   "This ACE was not inherited from its parent object"
7294 };
7295 static const true_false_string tfs_ace_flags_successful_access = {
7296   "Successful accesses will be audited",
7297   "Successful accesses will not be audited"
7298 };
7299 static const true_false_string tfs_ace_flags_failed_access = {
7300   "Failed accesses will be audited",
7301   "Failed accesses will not be audited"
7302 };
7303
7304 #define APPEND_ACE_TEXT(flag, item, string) \
7305         if(flag){                                                       \
7306                 if(item)                                                \
7307                         proto_item_append_text(item, string, sep);      \
7308                 sep = ", ";                                             \
7309         }
7310
7311 static int
7312 dissect_nt_v2_ace_flags(tvbuff_t *tvb, int offset, proto_tree *parent_tree,
7313                         guint8 *data)
7314 {
7315         proto_item *item = NULL;
7316         proto_tree *tree = NULL;
7317         guint8 mask;
7318         char *sep = " ";
7319
7320         mask = tvb_get_guint8(tvb, offset);
7321
7322         if (data)
7323                 *data = mask;
7324
7325
7326         if(parent_tree){
7327                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7328                                            "NT ACE Flags: 0x%02x", mask);
7329                 tree = proto_item_add_subtree(item, ett_smb_ace_flags);
7330         }
7331
7332         proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
7333                        tvb, offset, 1, mask);
7334         APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
7335
7336         proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
7337                        tvb, offset, 1, mask);
7338         APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
7339
7340         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
7341                        tvb, offset, 1, mask);
7342         APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
7343
7344         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
7345                        tvb, offset, 1, mask);
7346         APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
7347
7348         proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
7349                        tvb, offset, 1, mask);
7350         APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
7351
7352         proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
7353                        tvb, offset, 1, mask);
7354         APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
7355
7356         proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
7357                        tvb, offset, 1, mask);
7358         APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
7359
7360
7361         offset += 1;
7362         return offset;
7363 }
7364
7365 /* Dissect an access mask.  All this stuff is kind of explained at MSDN:
7366
7367 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/windows_2000_windows_nt_access_mask_format.asp
7368
7369 */
7370
7371 static gint ett_nt_access_mask = -1;
7372 static gint ett_nt_access_mask_generic = -1;
7373 static gint ett_nt_access_mask_standard = -1;
7374 static gint ett_nt_access_mask_specific = -1;
7375
7376 static int hf_access_sacl = -1;
7377 static int hf_access_maximum_allowed = -1;
7378 static int hf_access_generic_read = -1;
7379 static int hf_access_generic_write = -1;
7380 static int hf_access_generic_execute = -1;
7381 static int hf_access_generic_all = -1;
7382 static int hf_access_standard_delete = -1;
7383 static int hf_access_standard_read_control = -1;
7384 static int hf_access_standard_synchronise = -1;
7385 static int hf_access_standard_write_dac = -1;
7386 static int hf_access_standard_write_owner = -1;
7387 static int hf_access_specific_15 = -1;
7388 static int hf_access_specific_14 = -1;
7389 static int hf_access_specific_13 = -1;
7390 static int hf_access_specific_12 = -1;
7391 static int hf_access_specific_11 = -1;
7392 static int hf_access_specific_10 = -1;
7393 static int hf_access_specific_9 = -1;
7394 static int hf_access_specific_8 = -1;
7395 static int hf_access_specific_7 = -1;
7396 static int hf_access_specific_6 = -1;
7397 static int hf_access_specific_5 = -1;
7398 static int hf_access_specific_4 = -1;
7399 static int hf_access_specific_3 = -1;
7400 static int hf_access_specific_2 = -1;
7401 static int hf_access_specific_1 = -1;
7402 static int hf_access_specific_0 = -1;
7403
7404 /* Map generic permissions to specific permissions */
7405
7406 static void map_generic_access(guint32 *access_mask, 
7407                                struct generic_mapping *mapping)
7408 {
7409         if (*access_mask & GENERIC_READ_ACCESS) {
7410                 *access_mask &= ~GENERIC_READ_ACCESS;
7411                 *access_mask |= mapping->generic_read;
7412         }
7413
7414         if (*access_mask & GENERIC_WRITE_ACCESS) {
7415                 *access_mask &= ~GENERIC_WRITE_ACCESS;
7416                 *access_mask |= mapping->generic_write;
7417         }
7418
7419         if (*access_mask & GENERIC_EXECUTE_ACCESS) {
7420                 *access_mask &= ~GENERIC_EXECUTE_ACCESS;
7421                 *access_mask |= mapping->generic_execute;
7422         }
7423
7424         if (*access_mask & GENERIC_ALL_ACCESS) {
7425                 *access_mask &= ~GENERIC_ALL_ACCESS;
7426                 *access_mask |= mapping->generic_all;
7427         }
7428 }
7429
7430 /* Map standard permissions to specific permissions */
7431
7432 static void map_standard_access(guint32 *access_mask,
7433                                 struct standard_mapping *mapping)
7434 {
7435         if (*access_mask & READ_CONTROL_ACCESS) {
7436                 *access_mask &= ~READ_CONTROL_ACCESS;
7437                 *access_mask |= mapping->std_read;
7438         }
7439
7440         if (*access_mask & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|
7441                             SYNCHRONIZE_ACCESS)) {
7442                 *access_mask &= ~(DELETE_ACCESS|WRITE_DAC_ACCESS|
7443                                   WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS);
7444                 *access_mask |= mapping->std_all;
7445         }
7446
7447 }
7448
7449 int
7450 dissect_nt_access_mask(tvbuff_t *tvb, gint offset, packet_info *pinfo,
7451                        proto_tree *tree, char *drep, int hfindex,
7452                        struct access_mask_info *ami)
7453 {
7454         proto_item *item;
7455         proto_tree *subtree, *generic_tree, *standard_tree, *specific_tree;
7456         guint32 access;
7457
7458         if (drep != NULL) {
7459                 /*
7460                  * Called from a DCE RPC protocol dissector, for a
7461                  * protocol where a 32-bit NDR integer contains
7462                  * an NT access mask; extract the access mask
7463                  * with an NDR call.
7464                  */
7465                 offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
7466                                             hfindex, &access);
7467         } else {
7468                 /*
7469                  * Called from SMB, where the access mask is just a
7470                  * 4-byte little-endian quantity with no special
7471                  * NDR alignment requirement; extract it with
7472                  * "tvb_get_letohl()".
7473                  */
7474                 access = tvb_get_letohl(tvb, offset);
7475                 offset += 4;
7476         }
7477
7478         item = proto_tree_add_uint(tree, hfindex, tvb, offset - 4, 4, access);
7479
7480         subtree = proto_item_add_subtree(item, ett_nt_access_mask);
7481
7482         /* Generic access rights */
7483
7484         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7485                                    "Generic rights: 0x%08x",
7486                                    access & GENERIC_RIGHTS_MASK);
7487
7488         generic_tree = proto_item_add_subtree(
7489                 item, ett_nt_access_mask_generic);
7490
7491         proto_tree_add_boolean(
7492                 generic_tree, hf_access_generic_read, tvb, offset - 4, 4,
7493                 access);
7494
7495         proto_tree_add_boolean(
7496                 generic_tree, hf_access_generic_write, tvb, offset - 4, 4,
7497                 access);
7498
7499         proto_tree_add_boolean(
7500                 generic_tree, hf_access_generic_execute, tvb, offset - 4, 4,
7501                 access);
7502
7503         proto_tree_add_boolean(
7504                 generic_tree, hf_access_generic_all, tvb, offset - 4, 4,
7505                 access);
7506
7507         /* Reserved (??) */
7508
7509         proto_tree_add_boolean(
7510                 subtree, hf_access_maximum_allowed, tvb, offset - 4, 4,
7511                 access);
7512
7513         /* Access system security */
7514
7515         proto_tree_add_boolean(
7516                 subtree, hf_access_sacl, tvb, offset - 4, 4,
7517                 access);
7518
7519         /* Standard access rights */
7520
7521         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7522                                    "Standard rights: 0x%08x",
7523                                    access & STANDARD_RIGHTS_MASK);
7524
7525         standard_tree = proto_item_add_subtree(
7526                 item, ett_nt_access_mask_standard);
7527
7528         proto_tree_add_boolean(
7529                 standard_tree, hf_access_standard_synchronise, tvb, 
7530                 offset - 4, 4, access);
7531
7532         proto_tree_add_boolean(
7533                 standard_tree, hf_access_standard_write_owner, tvb, 
7534                 offset - 4, 4, access);
7535
7536         proto_tree_add_boolean(
7537                 standard_tree, hf_access_standard_write_dac, tvb, 
7538                 offset - 4, 4, access);
7539
7540         proto_tree_add_boolean(
7541                 standard_tree, hf_access_standard_read_control, tvb, 
7542                 offset - 4, 4, access);
7543
7544         proto_tree_add_boolean(
7545                 standard_tree, hf_access_standard_delete, tvb, offset - 4, 4,
7546                 access);
7547
7548         /* Specific access rights.  Call the specific_rights_fn
7549            pointer if we have one, otherwise just display bits 0-15 in
7550            boring fashion. */
7551
7552         if (ami && ami->specific_rights_name)
7553                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7554                                            "%s specific rights: 0x%08x",
7555                                            ami->specific_rights_name,
7556                                            access & SPECIFIC_RIGHTS_MASK);
7557         else
7558                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7559                                            "Specific rights: 0x%08x",
7560                                            access & SPECIFIC_RIGHTS_MASK);
7561
7562         specific_tree = proto_item_add_subtree(
7563                 item, ett_nt_access_mask_specific);
7564
7565         if (ami && ami->specific_rights_fn) {
7566                 guint32 mapped_access = access;
7567                 proto_tree *specific_mapped;
7568
7569                 specific_mapped = proto_item_add_subtree(
7570                         item, ett_nt_access_mask_specific);
7571
7572                 ami->specific_rights_fn(
7573                         tvb, offset - 4, specific_tree, access);
7574
7575                 if (ami->generic_mapping)
7576                         map_generic_access(&access, ami->generic_mapping);
7577                 
7578                 if (ami->standard_mapping)
7579                         map_standard_access(&access, ami->standard_mapping);
7580
7581                 if (access != mapped_access) {
7582                         ami->specific_rights_fn(
7583                                 tvb, offset - 4, specific_mapped, 
7584                                 mapped_access);
7585                 }
7586                 
7587                 return offset;
7588         }
7589
7590         proto_tree_add_boolean(
7591                 specific_tree, hf_access_specific_15, tvb, offset - 4, 4,
7592                 access);
7593
7594         proto_tree_add_boolean(
7595                 specific_tree, hf_access_specific_14, tvb, offset - 4, 4,
7596                 access);
7597
7598         proto_tree_add_boolean(
7599                 specific_tree, hf_access_specific_13, tvb, offset - 4, 4,
7600                 access);
7601
7602         proto_tree_add_boolean(
7603                 specific_tree, hf_access_specific_12, tvb, offset - 4, 4,
7604                 access);
7605
7606         proto_tree_add_boolean(
7607                 specific_tree, hf_access_specific_11, tvb, offset - 4, 4,
7608                 access);
7609
7610         proto_tree_add_boolean(
7611                 specific_tree, hf_access_specific_10, tvb, offset - 4, 4,
7612                 access);
7613
7614         proto_tree_add_boolean(
7615                 specific_tree, hf_access_specific_9, tvb, offset - 4, 4,
7616                 access);
7617
7618         proto_tree_add_boolean(
7619                 specific_tree, hf_access_specific_8, tvb, offset - 4, 4,
7620                 access);
7621
7622         proto_tree_add_boolean(
7623                 specific_tree, hf_access_specific_7, tvb, offset - 4, 4,
7624                 access);
7625
7626         proto_tree_add_boolean(
7627                 specific_tree, hf_access_specific_6, tvb, offset - 4, 4,
7628                 access);
7629
7630         proto_tree_add_boolean(
7631                 specific_tree, hf_access_specific_5, tvb, offset - 4, 4,
7632                 access);
7633
7634         proto_tree_add_boolean(
7635                 specific_tree, hf_access_specific_4, tvb, offset - 4, 4,
7636                 access);
7637
7638         proto_tree_add_boolean(
7639                 specific_tree, hf_access_specific_3, tvb, offset - 4, 4,
7640                 access);
7641
7642         proto_tree_add_boolean(
7643                 specific_tree, hf_access_specific_2, tvb, offset - 4, 4,
7644                 access);
7645
7646         proto_tree_add_boolean(
7647                 specific_tree, hf_access_specific_1, tvb, offset - 4, 4,
7648                 access);
7649
7650         proto_tree_add_boolean(
7651                 specific_tree, hf_access_specific_0, tvb, offset - 4, 4,
7652                 access);
7653
7654         return offset;
7655 }
7656
7657 static int hf_smb_access_mask = -1;
7658
7659 static int
7660 dissect_nt_v2_ace(tvbuff_t *tvb, int offset, packet_info *pinfo,
7661                   proto_tree *parent_tree, char *drep,
7662                   struct access_mask_info *ami)
7663 {
7664         proto_item *item = NULL;
7665         proto_tree *tree = NULL;
7666         int old_offset = offset;
7667         guint16 size;
7668         char *sid_str = NULL;
7669         guint8 type;
7670         guint8 flags;
7671
7672         if(parent_tree){
7673                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7674                                            "NT ACE: ");
7675                 tree = proto_item_add_subtree(item, ett_smb_ace);
7676         }
7677
7678         /* type */
7679         type = tvb_get_guint8(tvb, offset);
7680         proto_tree_add_uint(tree, hf_smb_ace_type, tvb, offset, 1, type);
7681         offset += 1;
7682
7683         /* flags */
7684         offset = dissect_nt_v2_ace_flags(tvb, offset, tree, &flags);
7685
7686         /* size */
7687         size = tvb_get_letohs(tvb, offset);
7688         proto_tree_add_uint(tree, hf_smb_ace_size, tvb, offset, 2, size);
7689         offset += 2;
7690
7691         /* access mask */
7692         offset = dissect_nt_access_mask(
7693                 tvb, offset, pinfo, tree, drep, hf_smb_access_mask, ami);
7694
7695         /* SID */
7696         offset = dissect_nt_sid(tvb, offset, tree, "ACE", &sid_str, -1);
7697
7698         if (item)
7699                 proto_item_append_text(
7700                         item, "%s, flags 0x%02x, %s", sid_str, flags,
7701                         val_to_str(type, ace_type_vals, "Unknown ACE type (0x%02x)"));
7702
7703         g_free(sid_str);
7704
7705         proto_item_set_len(item, offset-old_offset);
7706
7707         /* Sometimes there is some spare space at the end of the ACE so use
7708            the size field to work out where the end is. */
7709
7710         return old_offset + size;
7711 }
7712
7713 static int
7714 dissect_nt_acl(tvbuff_t *tvb, int offset, packet_info *pinfo,
7715                proto_tree *parent_tree, char *drep, char *name,
7716                struct access_mask_info *ami)
7717 {
7718         proto_item *item = NULL;
7719         proto_tree *tree = NULL;
7720         int old_offset = offset;
7721         guint16 revision;
7722         guint32 num_aces;
7723
7724         if(parent_tree){
7725                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7726                                            "NT %s ACL", name);
7727                 tree = proto_item_add_subtree(item, ett_smb_acl);
7728         }
7729
7730         /* revision */
7731         revision = tvb_get_letohs(tvb, offset);
7732         proto_tree_add_uint(tree, hf_smb_acl_revision,
7733                 tvb, offset, 2, revision);
7734         offset += 2;
7735
7736         switch(revision){
7737         case 2:  /* only version we will ever see of this structure?*/
7738         case 3:
7739           /* size */
7740           proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
7741           offset += 2;
7742
7743           /* number of ace structures */
7744           num_aces = tvb_get_letohl(tvb, offset);
7745           proto_tree_add_uint(tree, hf_smb_acl_num_aces,
7746                               tvb, offset, 4, num_aces);
7747           offset += 4;
7748
7749           while(num_aces--){
7750             offset=dissect_nt_v2_ace(
7751                     tvb, offset, pinfo, tree, drep, ami);
7752           }
7753         }
7754
7755         proto_item_set_len(item, offset-old_offset);
7756         return offset;
7757 }
7758
7759 static const true_false_string tfs_sec_desc_type_owner_defaulted = {
7760   "OWNER is DEFAULTED",
7761   "Owner is NOT defaulted"
7762 };
7763 static const true_false_string tfs_sec_desc_type_group_defaulted = {
7764   "GROUP is DEFAULTED",
7765   "Group is NOT defaulted"
7766 };
7767 static const true_false_string tfs_sec_desc_type_dacl_present = {
7768   "DACL is PRESENT",
7769   "DACL is NOT present"
7770 };
7771 static const true_false_string tfs_sec_desc_type_dacl_defaulted = {
7772   "DACL is DEFAULTED",
7773   "DACL is NOT defaulted"
7774 };
7775 static const true_false_string tfs_sec_desc_type_sacl_present = {
7776   "SACL is PRESENT",
7777   "SACL is NOT present"
7778 };
7779 static const true_false_string tfs_sec_desc_type_sacl_defaulted = {
7780   "SACL is DEFAULTED",
7781   "SACL is NOT defaulted"
7782 };
7783 static const true_false_string tfs_sec_desc_type_dacl_auto_inherit_req = {
7784   "DACL has AUTO INHERIT REQUIRED",
7785   "DACL does NOT require auto inherit"
7786 };
7787 static const true_false_string tfs_sec_desc_type_sacl_auto_inherit_req = {
7788   "SACL has AUTO INHERIT REQUIRED",
7789   "SACL does NOT require auto inherit"
7790 };
7791 static const true_false_string tfs_sec_desc_type_dacl_auto_inherited = {
7792   "DACL is AUTO INHERITED",
7793   "DACL is NOT auto inherited"
7794 };
7795 static const true_false_string tfs_sec_desc_type_sacl_auto_inherited = {
7796   "SACL is AUTO INHERITED",
7797   "SACL is NOT auto inherited"
7798 };
7799 static const true_false_string tfs_sec_desc_type_dacl_protected = {
7800   "The DACL is PROTECTED",
7801   "The DACL is NOT protected"
7802 };
7803 static const true_false_string tfs_sec_desc_type_sacl_protected = {
7804   "The SACL is PROTECTED",
7805   "The SACL is NOT protected"
7806 };
7807 static const true_false_string tfs_sec_desc_type_self_relative = {
7808   "This SecDesc is SELF RELATIVE",
7809   "This SecDesc is NOT self relative"
7810 };
7811
7812
7813 static int
7814 dissect_nt_sec_desc_type(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7815 {
7816         proto_item *item = NULL;
7817         proto_tree *tree = NULL;
7818         guint16 mask;
7819
7820         mask = tvb_get_letohs(tvb, offset);
7821         if(parent_tree){
7822                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7823                                            "Type: 0x%04x", mask);
7824                 tree = proto_item_add_subtree(item, ett_smb_sec_desc_type);
7825         }
7826
7827         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_self_relative,
7828                                tvb, offset, 2, mask);
7829         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_protected,
7830                                tvb, offset, 2, mask);
7831         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_protected,
7832                                tvb, offset, 2, mask);
7833         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherited,
7834                                tvb, offset, 2, mask);
7835         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherited,
7836                                tvb, offset, 2, mask);
7837         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherit_req,
7838                                tvb, offset, 2, mask);
7839         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherit_req,
7840                                tvb, offset, 2, mask);
7841         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_defaulted,
7842                                tvb, offset, 2, mask);
7843         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_present,
7844                                tvb, offset, 2, mask);
7845         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_defaulted,
7846                                tvb, offset, 2, mask);
7847         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_present,
7848                                tvb, offset, 2, mask);
7849         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_group_defaulted,
7850                                tvb, offset, 2, mask);
7851         proto_tree_add_boolean(tree, hf_smb_sec_desc_type_owner_defaulted,
7852                                tvb, offset, 2, mask);
7853
7854
7855         offset += 2;
7856         return offset;
7857 }
7858
7859 int
7860 dissect_nt_sec_desc(tvbuff_t *tvb, int offset, packet_info *pinfo,
7861                     proto_tree *parent_tree, char *drep, int len, 
7862                     struct access_mask_info *ami)
7863 {
7864         proto_item *item = NULL;
7865         proto_tree *tree = NULL;
7866         guint8 revision;
7867         int old_offset = offset;
7868         guint32 owner_sid_offset;
7869         guint32 group_sid_offset;
7870         guint32 sacl_offset;
7871         guint32 dacl_offset;
7872
7873         if(parent_tree){
7874                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7875                                            "NT Security Descriptor");
7876                 tree = proto_item_add_subtree(item, ett_smb_sec_desc);
7877         }
7878
7879         /* revision */
7880         revision = tvb_get_guint8(tvb, offset);
7881         proto_tree_add_uint(tree, hf_smb_sec_desc_revision,
7882                 tvb, offset, 1, revision);
7883         offset += 1;
7884
7885         /* next byte should be zero, for now just ignore it */
7886         offset += 1;
7887
7888
7889         switch(revision){
7890         case 1:  /* only version we will ever see of this structure?*/
7891           /* type */
7892           offset = dissect_nt_sec_desc_type(tvb, offset, tree);
7893
7894           /* offset to owner sid */
7895           owner_sid_offset = tvb_get_letohl(tvb, offset);
7896           proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %u", owner_sid_offset);
7897           offset += 4;
7898
7899           /* offset to group sid */
7900           group_sid_offset = tvb_get_letohl(tvb, offset);
7901           proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %u", group_sid_offset);
7902           offset += 4;
7903
7904           /* offset to sacl */
7905           sacl_offset = tvb_get_letohl(tvb, offset);
7906           proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %u", sacl_offset);
7907           offset += 4;
7908
7909           /* offset to dacl */
7910           dacl_offset = tvb_get_letohl(tvb, offset);
7911           proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %u", dacl_offset);
7912           offset += 4;
7913
7914           /*owner SID*/
7915           if(owner_sid_offset){
7916             if (len == -1)
7917               offset = dissect_nt_sid(tvb, offset, tree, "Owner", NULL, -1);
7918             else
7919               dissect_nt_sid(
7920                       tvb, old_offset+owner_sid_offset, tree, "Owner", NULL, -1);
7921           }
7922
7923           /*group SID*/
7924           if(group_sid_offset){
7925             dissect_nt_sid(
7926                     tvb, old_offset+group_sid_offset, tree, "Group", NULL, -1);
7927           }
7928
7929           /* sacl */
7930           if(sacl_offset){
7931             dissect_nt_acl(tvb, old_offset+sacl_offset, pinfo, tree, 
7932                            drep, "System (SACL)", ami);
7933           }
7934
7935           /* dacl */
7936           if(dacl_offset){
7937             dissect_nt_acl(tvb, old_offset+dacl_offset, pinfo, tree, 
7938                            drep, "User (DACL)", ami);
7939           }
7940
7941         }
7942
7943         return offset+len;
7944 }
7945
7946 static int
7947 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
7948 {
7949         int old_offset, old_sid_offset;
7950         guint32 qsize;
7951
7952         do {
7953                 old_offset=offset;
7954
7955                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7956                 qsize=tvb_get_letohl(tvb, offset);
7957                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
7958                 COUNT_BYTES_TRANS_SUBR(4);
7959
7960                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7961                 /* length of SID */
7962                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7963                 COUNT_BYTES_TRANS_SUBR(4);
7964
7965                 /* 16 unknown bytes */
7966                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7967                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7968                             offset, 8, TRUE);
7969                 COUNT_BYTES_TRANS_SUBR(8);
7970
7971                 /* number of bytes for used quota */
7972                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7973                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
7974                 COUNT_BYTES_TRANS_SUBR(8);
7975
7976                 /* number of bytes for quota warning */
7977                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7978                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
7979                 COUNT_BYTES_TRANS_SUBR(8);
7980
7981                 /* number of bytes for quota limit */
7982                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7983                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
7984                 COUNT_BYTES_TRANS_SUBR(8);
7985
7986                 /* SID of the user */
7987                 old_sid_offset=offset;
7988                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
7989                 *bcp -= (offset-old_sid_offset);
7990
7991                 if(qsize){
7992                         offset = old_offset+qsize;
7993                 }
7994         }while(qsize);
7995
7996
7997         return offset;
7998 }
7999
8000
8001 static int
8002 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
8003 {
8004         proto_item *item = NULL;
8005         proto_tree *tree = NULL;
8006         smb_info_t *si;
8007         int old_offset = offset;
8008         guint16 bcp=bc; /* XXX fixme */
8009
8010         si = (smb_info_t *)pinfo->private_data;
8011
8012         if(parent_tree){
8013                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
8014                                 "%s Data",
8015                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8016                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8017         }
8018
8019         switch(ntd->subcmd){
8020         case NT_TRANS_CREATE:
8021                 /* security descriptor */
8022                 if(ntd->sd_len){
8023                         offset = dissect_nt_sec_desc(
8024                                 tvb, offset, pinfo, tree, NULL, ntd->sd_len, 
8025                                 NULL);
8026                 }
8027
8028                 /* extended attributes */
8029                 if(ntd->ea_len){
8030                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
8031                         offset += ntd->ea_len;
8032                 }
8033
8034                 break;
8035         case NT_TRANS_IOCTL:
8036                 /* ioctl data */
8037                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
8038                 offset += bc;
8039
8040                 break;
8041         case NT_TRANS_SSD:
8042                 offset = dissect_nt_sec_desc(
8043                         tvb, offset, pinfo, tree, NULL, bc, NULL);
8044                 break;
8045         case NT_TRANS_NOTIFY:
8046                 break;
8047         case NT_TRANS_RENAME:
8048                 /* XXX not documented */
8049                 break;
8050         case NT_TRANS_QSD:
8051                 break;
8052         case NT_TRANS_GET_USER_QUOTA:
8053                 /* unknown 4 bytes */
8054                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8055                             offset, 4, TRUE);
8056                 offset += 4;
8057
8058                 /* length of SID */
8059                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
8060                 offset +=4;
8061
8062                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8063                 break;
8064         case NT_TRANS_SET_USER_QUOTA:
8065                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8066                 break;
8067         }
8068
8069         /* ooops there were data we didnt know how to process */
8070         if((offset-old_offset) < bc){
8071                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
8072                     bc - (offset-old_offset), TRUE);
8073                 offset += bc - (offset-old_offset);
8074         }
8075
8076         return offset;
8077 }
8078
8079 static int
8080 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)
8081 {
8082         proto_item *item = NULL;
8083         proto_tree *tree = NULL;
8084         smb_info_t *si;
8085         guint32 fn_len;
8086         const char *fn;
8087
8088         si = (smb_info_t *)pinfo->private_data;
8089
8090         if(parent_tree){
8091                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8092                                 "%s Parameters",
8093                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8094                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8095         }
8096
8097         switch(ntd->subcmd){
8098         case NT_TRANS_CREATE:
8099                 /* Create flags */
8100                 offset = dissect_nt_create_bits(tvb, tree, offset);
8101                 bc -= 4;
8102
8103                 /* root directory fid */
8104                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
8105                 COUNT_BYTES(4);
8106
8107                 /* nt access mask */
8108                 offset = dissect_smb_access_mask(tvb, tree, offset);
8109                 bc -= 4;
8110
8111                 /* allocation size */
8112                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8113                 COUNT_BYTES(8);
8114
8115                 /* Extended File Attributes */
8116                 offset = dissect_file_ext_attr(tvb, tree, offset);
8117                 bc -= 4;
8118
8119                 /* share access */
8120                 offset = dissect_nt_share_access(tvb, tree, offset);
8121                 bc -= 4;
8122
8123                 /* create disposition */
8124                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8125                 COUNT_BYTES(4);
8126
8127                 /* create options */
8128                 offset = dissect_nt_create_options(tvb, tree, offset);
8129                 bc -= 4;
8130
8131                 /* sd length */
8132                 ntd->sd_len = tvb_get_letohl(tvb, offset);
8133                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
8134                 COUNT_BYTES(4);
8135
8136                 /* ea length */
8137                 ntd->ea_len = tvb_get_letohl(tvb, offset);
8138                 proto_tree_add_uint(tree, hf_smb_ea_list_length, tvb, offset, 4, ntd->ea_len);
8139                 COUNT_BYTES(4);
8140
8141                 /* file name len */
8142                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
8143                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8144                 COUNT_BYTES(4);
8145
8146                 /* impersonation level */
8147                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8148                 COUNT_BYTES(4);
8149
8150                 /* security flags */
8151                 offset = dissect_nt_security_flags(tvb, tree, offset);
8152                 bc -= 1;
8153
8154                 /* file name */
8155                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8156                 if (fn != NULL) {
8157                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8158                                 fn);
8159                         COUNT_BYTES(fn_len);
8160                 }
8161
8162                 break;
8163         case NT_TRANS_IOCTL:
8164                 break;
8165         case NT_TRANS_SSD: {
8166                 guint16 fid;
8167
8168                 /* fid */
8169                 fid = tvb_get_letohs(tvb, offset);
8170                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8171                 offset += 2;
8172
8173                 /* 2 reserved bytes */
8174                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8175                 offset += 2;
8176
8177                 /* security information */
8178                 offset = dissect_security_information_mask(tvb, tree, offset);
8179                 break;
8180         }
8181         case NT_TRANS_NOTIFY:
8182                 break;
8183         case NT_TRANS_RENAME:
8184                 /* XXX not documented */
8185                 break;
8186         case NT_TRANS_QSD: {
8187                 guint16 fid;
8188
8189                 /* fid */
8190                 fid = tvb_get_letohs(tvb, offset);
8191                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8192                 offset += 2;
8193
8194                 /* 2 reserved bytes */
8195                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8196                 offset += 2;
8197
8198                 /* security information */
8199                 offset = dissect_security_information_mask(tvb, tree, offset);
8200                 break;
8201         }
8202         case NT_TRANS_GET_USER_QUOTA:
8203                 /* not decoded yet */
8204                 break;
8205         case NT_TRANS_SET_USER_QUOTA:
8206                 /* not decoded yet */
8207                 break;
8208         }
8209
8210         return offset;
8211 }
8212
8213 static int
8214 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
8215 {
8216         proto_item *item = NULL;
8217         proto_tree *tree = NULL;
8218         smb_info_t *si;
8219         int old_offset = offset;
8220
8221         si = (smb_info_t *)pinfo->private_data;
8222
8223         if(parent_tree){
8224                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8225                                 "%s Setup",
8226                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8227                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8228         }
8229
8230         switch(ntd->subcmd){
8231         case NT_TRANS_CREATE:
8232                 break;
8233         case NT_TRANS_IOCTL: {
8234                 guint16 fid;
8235
8236                 /* function code */
8237                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
8238                 offset += 4;
8239
8240                 /* fid */
8241                 fid = tvb_get_letohs(tvb, offset);
8242                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8243                 offset += 2;
8244
8245                 /* isfsctl */
8246                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
8247                 offset += 1;
8248
8249                 /* isflags */
8250                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
8251
8252                 break;
8253         }
8254         case NT_TRANS_SSD:
8255                 break;
8256         case NT_TRANS_NOTIFY: {
8257                 guint16 fid;
8258
8259                 /* completion filter */
8260                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
8261
8262                 /* fid */
8263                 fid = tvb_get_letohs(tvb, offset);
8264                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8265                 offset += 2;
8266
8267                 /* watch tree */
8268                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
8269                 offset += 1;
8270
8271                 /* reserved byte */
8272                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8273                 offset += 1;
8274
8275                 break;
8276         }
8277         case NT_TRANS_RENAME:
8278                 /* XXX not documented */
8279                 break;
8280         case NT_TRANS_QSD:
8281                 break;
8282         case NT_TRANS_GET_USER_QUOTA:
8283                 /* not decoded yet */
8284                 break;
8285         case NT_TRANS_SET_USER_QUOTA:
8286                 /* not decoded yet */
8287                 break;
8288         }
8289
8290         return old_offset+len;
8291 }
8292
8293
8294 static int
8295 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8296 {
8297         guint8 wc, sc;
8298         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
8299         smb_info_t *si;
8300         smb_saved_info_t *sip;
8301         int subcmd;
8302         nt_trans_data ntd;
8303         guint16 bc;
8304         int padcnt;
8305         smb_nt_transact_info_t *nti;
8306
8307         si = (smb_info_t *)pinfo->private_data;
8308         sip = si->sip;
8309
8310         WORD_COUNT;
8311
8312         if(wc>=19){
8313                 /* primary request */
8314                 /* max setup count */
8315                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
8316                 offset += 1;
8317
8318                 /* 2 reserved bytes */
8319                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8320                 offset += 2;
8321         } else {
8322                 /* secondary request */
8323                 /* 3 reserved bytes */
8324                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8325                 offset += 3;
8326         }
8327
8328
8329         /* total param count */
8330         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
8331         offset += 4;
8332
8333         /* total data count */
8334         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
8335         offset += 4;
8336
8337         if(wc>=19){
8338                 /* primary request */
8339                 /* max param count */
8340                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
8341                 offset += 4;
8342
8343                 /* max data count */
8344                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
8345                 offset += 4;
8346         }
8347
8348         /* param count */
8349         pc = tvb_get_letohl(tvb, offset);
8350         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8351         offset += 4;
8352
8353         /* param offset */
8354         po = tvb_get_letohl(tvb, offset);
8355         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8356         offset += 4;
8357
8358         /* param displacement */
8359         if(wc>=19){
8360                 /* primary request*/
8361                 pd = 0;
8362         } else {
8363                 /* secondary request */
8364                 pd = tvb_get_letohl(tvb, offset);
8365                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8366                 offset += 4;
8367         }
8368
8369         /* data count */
8370         dc = tvb_get_letohl(tvb, offset);
8371         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8372         offset += 4;
8373
8374         /* data offset */
8375         od = tvb_get_letohl(tvb, offset);
8376         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8377         offset += 4;
8378
8379         /* data displacement */
8380         if(wc>=19){
8381                 /* primary request */
8382                 dd = 0;
8383         } else {
8384                 /* secondary request */
8385                 dd = tvb_get_letohl(tvb, offset);
8386                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8387                 offset += 4;
8388         }
8389
8390         /* setup count */
8391         if(wc>=19){
8392                 /* primary request */
8393                 sc = tvb_get_guint8(tvb, offset);
8394                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8395                 offset += 1;
8396         } else {
8397                 /* secondary request */
8398                 sc = 0;
8399         }
8400
8401         /* function */
8402         if(wc>=19){
8403                 /* primary request */
8404                 subcmd = tvb_get_letohs(tvb, offset);
8405                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
8406                 if(check_col(pinfo->cinfo, COL_INFO)){
8407                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8408                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
8409                 }
8410                 ntd.subcmd = subcmd;
8411                 if (!si->unidir) {
8412                         if(!pinfo->fd->flags.visited){
8413                                 /*
8414                                  * Allocate a new smb_nt_transact_info_t
8415                                  * structure.
8416                                  */
8417                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
8418                                 nti->subcmd = subcmd;
8419                                 sip->extra_info = nti;
8420                         }
8421                 }
8422         } else {
8423                 /* secondary request */
8424                 if(check_col(pinfo->cinfo, COL_INFO)){
8425                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
8426                 }
8427         }
8428         offset += 2;
8429
8430         /* this is a padding byte */
8431         if(offset%1){
8432                 /* pad byte */
8433                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
8434                 offset += 1;
8435         }
8436
8437         /* if there were any setup bytes, decode them */
8438         if(sc){
8439                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
8440                 offset += sc*2;
8441         }
8442
8443         BYTE_COUNT;
8444
8445         /* parameters */
8446         if(po>(guint32)offset){
8447                 /* We have some initial padding bytes.
8448                 */
8449                 padcnt = po-offset;
8450                 if (padcnt > bc)
8451                         padcnt = bc;
8452                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8453                 COUNT_BYTES(padcnt);
8454         }
8455         if(pc){
8456                 CHECK_BYTE_COUNT(pc);
8457                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
8458                 COUNT_BYTES(pc);
8459         }
8460
8461         /* data */
8462         if(od>(guint32)offset){
8463                 /* We have some initial padding bytes.
8464                 */
8465                 padcnt = od-offset;
8466                 if (padcnt > bc)
8467                         padcnt = bc;
8468                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8469                 COUNT_BYTES(padcnt);
8470         }
8471         if(dc){
8472                 CHECK_BYTE_COUNT(dc);
8473                 dissect_nt_trans_data_request(
8474                         tvb, pinfo, offset, tree, dc, &ntd);
8475                 COUNT_BYTES(dc);
8476         }
8477
8478         END_OF_SMB
8479
8480         return offset;
8481 }
8482
8483
8484
8485 static int
8486 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
8487                                int offset, proto_tree *parent_tree, int len,
8488                                nt_trans_data *ntd _U_)
8489 {
8490         proto_item *item = NULL;
8491         proto_tree *tree = NULL;
8492         smb_info_t *si;
8493         smb_nt_transact_info_t *nti;
8494         guint16 bcp;
8495
8496         si = (smb_info_t *)pinfo->private_data;
8497         if (si->sip != NULL)
8498                 nti = si->sip->extra_info;
8499         else
8500                 nti = NULL;
8501
8502         if(parent_tree){
8503                 if(nti != NULL){
8504                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8505                                 "%s Data",
8506                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8507                 } else {
8508                         /*
8509                          * We never saw the request to which this is a
8510                          * response.
8511                          */
8512                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8513                                 "Unknown NT Transaction Data (matching request not seen)");
8514                 }
8515                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8516         }
8517
8518         if (nti == NULL) {
8519                 offset += len;
8520                 return offset;
8521         }
8522         switch(nti->subcmd){
8523         case NT_TRANS_CREATE:
8524                 break;
8525         case NT_TRANS_IOCTL:
8526                 /* ioctl data */
8527                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
8528                 offset += len;
8529
8530                 break;
8531         case NT_TRANS_SSD:
8532                 break;
8533         case NT_TRANS_NOTIFY:
8534                 break;
8535         case NT_TRANS_RENAME:
8536                 /* XXX not documented */
8537                 break;
8538         case NT_TRANS_QSD: {
8539                 /*
8540                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
8541                  * which may be documented in the Win32 documentation
8542                  * somewhere.
8543                  */
8544                 offset = dissect_nt_sec_desc(
8545                         tvb, offset, pinfo, tree, NULL, len, NULL);
8546                 break;
8547         }
8548         case NT_TRANS_GET_USER_QUOTA:
8549                 bcp=len;
8550                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8551                 break;
8552         case NT_TRANS_SET_USER_QUOTA:
8553                 /* not decoded yet */
8554                 break;
8555         }
8556
8557         return offset;
8558 }
8559
8560 static int
8561 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
8562                                 int offset, proto_tree *parent_tree,
8563                                 int len, nt_trans_data *ntd _U_, guint16 bc)
8564 {
8565         proto_item *item = NULL;
8566         proto_tree *tree = NULL;
8567         guint32 fn_len;
8568         const char *fn;
8569         smb_info_t *si;
8570         smb_nt_transact_info_t *nti;
8571         guint16 fid;
8572         int old_offset;
8573         guint32 neo;
8574         int padcnt;
8575
8576         si = (smb_info_t *)pinfo->private_data;
8577         if (si->sip != NULL)
8578                 nti = si->sip->extra_info;
8579         else
8580                 nti = NULL;
8581
8582         if(parent_tree){
8583                 if(nti != NULL){
8584                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8585                                 "%s Parameters",
8586                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8587                 } else {
8588                         /*
8589                          * We never saw the request to which this is a
8590                          * response.
8591                          */
8592                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8593                                 "Unknown NT Transaction Parameters (matching request not seen)");
8594                 }
8595                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8596         }
8597
8598         if (nti == NULL) {
8599                 offset += len;
8600                 return offset;
8601         }
8602         switch(nti->subcmd){
8603         case NT_TRANS_CREATE:
8604                 /* oplock level */
8605                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8606                 offset += 1;
8607
8608                 /* reserved byte */
8609                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8610                 offset += 1;
8611
8612                 /* fid */
8613                 fid = tvb_get_letohs(tvb, offset);
8614                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8615                 offset += 2;
8616
8617                 /* create action */
8618                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8619                 offset += 4;
8620
8621                 /* ea error offset */
8622                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
8623                 offset += 4;
8624
8625                 /* create time */
8626                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8627                         hf_smb_create_time);
8628
8629                 /* access time */
8630                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8631                         hf_smb_access_time);
8632
8633                 /* last write time */
8634                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8635                         hf_smb_last_write_time);
8636
8637                 /* last change time */
8638                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8639                         hf_smb_change_time);
8640
8641                 /* Extended File Attributes */
8642                 offset = dissect_file_ext_attr(tvb, tree, offset);
8643
8644                 /* allocation size */
8645                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8646                 offset += 8;
8647
8648                 /* end of file */
8649                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8650                 offset += 8;
8651
8652                 /* File Type */
8653                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8654                 offset += 2;
8655
8656                 /* device state */
8657                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8658
8659                 /* is directory */
8660                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8661                 offset += 1;
8662                 break;
8663         case NT_TRANS_IOCTL:
8664                 break;
8665         case NT_TRANS_SSD:
8666                 break;
8667         case NT_TRANS_NOTIFY:
8668                 while(len){
8669                         old_offset = offset;
8670
8671                         /* next entry offset */
8672                         neo = tvb_get_letohl(tvb, offset);
8673                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8674                         COUNT_BYTES(4);
8675                         len -= 4;
8676                         /* broken implementations */
8677                         if(len<0)break;
8678
8679                         /* action */
8680                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
8681                         COUNT_BYTES(4);
8682                         len -= 4;
8683                         /* broken implementations */
8684                         if(len<0)break;
8685
8686                         /* file name len */
8687                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
8688                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8689                         COUNT_BYTES(4);
8690                         len -= 4;
8691                         /* broken implementations */
8692                         if(len<0)break;
8693
8694                         /* file name */
8695                         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8696                         if (fn == NULL)
8697                                 break;
8698                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8699                                 fn);
8700                         COUNT_BYTES(fn_len);
8701                         len -= fn_len;
8702                         /* broken implementations */
8703                         if(len<0)break;
8704
8705                         if (neo == 0)
8706                                 break;  /* no more structures */
8707
8708                         /* skip to next structure */
8709                         padcnt = (old_offset + neo) - offset;
8710                         if (padcnt < 0) {
8711                                 /*
8712                                  * XXX - this is bogus; flag it?
8713                                  */
8714                                 padcnt = 0;
8715                         }
8716                         if (padcnt != 0) {
8717                                 COUNT_BYTES(padcnt);
8718                                 len -= padcnt;
8719                                 /* broken implementations */
8720                                 if(len<0)break;
8721                         }
8722                 }
8723                 break;
8724         case NT_TRANS_RENAME:
8725                 /* XXX not documented */
8726                 break;
8727         case NT_TRANS_QSD:
8728                 /*
8729                  * This appears to be the size of the security
8730                  * descriptor; the calling sequence of
8731                  * "ZwQuerySecurityObject()" suggests that it would
8732                  * be.  The actual security descriptor wouldn't
8733                  * follow if the max data count in the request
8734                  * was smaller; this lets the client know how
8735                  * big a buffer it needs to provide.
8736                  */
8737                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
8738                 offset += 4;
8739                 break;
8740         case NT_TRANS_GET_USER_QUOTA:
8741                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
8742                         tvb_get_letohl(tvb, offset));
8743                 offset += 4;
8744                 break;
8745         case NT_TRANS_SET_USER_QUOTA:
8746                 /* not decoded yet */
8747                 break;
8748         }
8749
8750         return offset;
8751 }
8752
8753 static int
8754 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
8755                                 int offset, proto_tree *parent_tree,
8756                                 int len, nt_trans_data *ntd _U_)
8757 {
8758         proto_item *item = NULL;
8759         proto_tree *tree = NULL;
8760         smb_info_t *si;
8761         smb_nt_transact_info_t *nti;
8762
8763         si = (smb_info_t *)pinfo->private_data;
8764         if (si->sip != NULL)
8765                 nti = si->sip->extra_info;
8766         else
8767                 nti = NULL;
8768
8769         if(parent_tree){
8770                 if(nti != NULL){
8771                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8772                                 "%s Setup",
8773                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8774                 } else {
8775                         /*
8776                          * We never saw the request to which this is a
8777                          * response.
8778                          */
8779                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8780                                 "Unknown NT Transaction Setup (matching request not seen)");
8781                 }
8782                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8783         }
8784
8785         if (nti == NULL) {
8786                 offset += len;
8787                 return offset;
8788         }
8789         switch(nti->subcmd){
8790         case NT_TRANS_CREATE:
8791                 break;
8792         case NT_TRANS_IOCTL:
8793                 break;
8794         case NT_TRANS_SSD:
8795                 break;
8796         case NT_TRANS_NOTIFY:
8797                 break;
8798         case NT_TRANS_RENAME:
8799                 /* XXX not documented */
8800                 break;
8801         case NT_TRANS_QSD:
8802                 break;
8803         case NT_TRANS_GET_USER_QUOTA:
8804                 /* not decoded yet */
8805                 break;
8806         case NT_TRANS_SET_USER_QUOTA:
8807                 /* not decoded yet */
8808                 break;
8809         }
8810
8811         return offset;
8812 }
8813
8814 static int
8815 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8816 {
8817         guint8 wc, sc;
8818         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
8819         guint32 td=0, tp=0;
8820         smb_info_t *si;
8821         smb_nt_transact_info_t *nti;
8822         static nt_trans_data ntd;
8823         guint16 bc;
8824         int padcnt;
8825         fragment_data *r_fd = NULL;
8826         tvbuff_t *pd_tvb=NULL;
8827         gboolean save_fragmented;
8828
8829         si = (smb_info_t *)pinfo->private_data;
8830         if (si->sip != NULL)
8831                 nti = si->sip->extra_info;
8832         else
8833                 nti = NULL;
8834
8835         /* primary request */
8836         if(nti != NULL){
8837                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
8838                 if(check_col(pinfo->cinfo, COL_INFO)){
8839                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8840                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
8841                 }
8842         } else {
8843                 proto_tree_add_text(tree, tvb, offset, 0,
8844                         "Function: <unknown function - could not find matching request>");
8845                 if(check_col(pinfo->cinfo, COL_INFO)){
8846                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
8847                 }
8848         }
8849
8850         WORD_COUNT;
8851
8852         /* 3 reserved bytes */
8853         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8854         offset += 3;
8855
8856         /* total param count */
8857         tp = tvb_get_letohl(tvb, offset);
8858         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8859         offset += 4;
8860
8861         /* total data count */
8862         td = tvb_get_letohl(tvb, offset);
8863         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8864         offset += 4;
8865
8866         /* param count */
8867         pc = tvb_get_letohl(tvb, offset);
8868         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8869         offset += 4;
8870
8871         /* param offset */
8872         po = tvb_get_letohl(tvb, offset);
8873         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8874         offset += 4;
8875
8876         /* param displacement */
8877         pd = tvb_get_letohl(tvb, offset);
8878         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8879         offset += 4;
8880
8881         /* data count */
8882         dc = tvb_get_letohl(tvb, offset);
8883         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8884         offset += 4;
8885
8886         /* data offset */
8887         od = tvb_get_letohl(tvb, offset);
8888         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8889         offset += 4;
8890
8891         /* data displacement */
8892         dd = tvb_get_letohl(tvb, offset);
8893         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8894         offset += 4;
8895
8896         /* setup count */
8897         sc = tvb_get_guint8(tvb, offset);
8898         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8899         offset += 1;
8900
8901         /* setup data */
8902         if(sc){
8903                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
8904                 offset += sc*2;
8905         }
8906
8907         BYTE_COUNT;
8908
8909         /* reassembly of SMB NT Transaction data payload.
8910            In this section we do reassembly of both the data and parameters
8911            blocks of the SMB transaction command.
8912         */
8913         save_fragmented = pinfo->fragmented;
8914         /* do we need reassembly? */
8915         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
8916                 /* oh yeah, either data or parameter section needs
8917                    reassembly...
8918                 */
8919                 pinfo->fragmented = TRUE;
8920                 if(smb_trans_reassembly){
8921                         /* ...and we were told to do reassembly */
8922                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
8923                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8924                                                              po, pc, pd, td+tp);
8925
8926                         }
8927                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
8928                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8929                                                              od, dc, dd+tp, td+tp);
8930                         }
8931                 }
8932         }
8933
8934         /* if we got a reassembled fd structure from the reassembly routine we
8935            must create pd_tvb from it
8936         */
8937         if(r_fd){
8938                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
8939                                              r_fd->datalen);
8940                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
8941                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
8942
8943                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
8944         }
8945
8946
8947         if(pd_tvb){
8948           /* we have reassembled data, grab param and data from there */
8949           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
8950                                           &ntd, tvb_length(pd_tvb));
8951           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
8952         } else {
8953           /* we do not have reassembled data, just use what we have in the
8954              packet as well as we can */
8955           /* parameters */
8956           if(po>(guint32)offset){
8957             /* We have some initial padding bytes.
8958              */
8959             padcnt = po-offset;
8960             if (padcnt > bc)
8961               padcnt = bc;
8962             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8963             COUNT_BYTES(padcnt);
8964           }
8965           if(pc){
8966             CHECK_BYTE_COUNT(pc);
8967             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
8968             COUNT_BYTES(pc);
8969           }
8970
8971           /* data */
8972           if(od>(guint32)offset){
8973             /* We have some initial padding bytes.
8974              */
8975             padcnt = od-offset;
8976             if (padcnt > bc)
8977               padcnt = bc;
8978             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8979             COUNT_BYTES(padcnt);
8980           }
8981           if(dc){
8982             CHECK_BYTE_COUNT(dc);
8983             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
8984             COUNT_BYTES(dc);
8985           }
8986         }
8987         pinfo->fragmented = save_fragmented;
8988
8989         END_OF_SMB
8990
8991         return offset;
8992 }
8993
8994 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8995    NT Transaction command  ends here
8996    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8997
8998 static const value_string print_mode_vals[] = {
8999         {0,     "Text Mode"},
9000         {1,     "Graphics Mode"},
9001         {0, NULL}
9002 };
9003
9004 static int
9005 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9006 {
9007         smb_info_t *si = pinfo->private_data;
9008         int fn_len;
9009         const char *fn;
9010         guint8 wc;
9011         guint16 bc;
9012
9013         WORD_COUNT;
9014
9015         /* setup len */
9016         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
9017         offset += 2;
9018
9019         /* print mode */
9020         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
9021         offset += 2;
9022
9023         BYTE_COUNT;
9024
9025         /* buffer format */
9026         CHECK_BYTE_COUNT(1);
9027         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9028         COUNT_BYTES(1);
9029
9030         /* print identifier */
9031         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
9032         if (fn == NULL)
9033                 goto endofcommand;
9034         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
9035                 fn);
9036         COUNT_BYTES(fn_len);
9037
9038         END_OF_SMB
9039
9040         return offset;
9041 }
9042
9043
9044 static int
9045 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9046 {
9047         int cnt;
9048         guint8 wc;
9049         guint16 bc, fid;
9050
9051         WORD_COUNT;
9052
9053         /* fid */
9054         fid = tvb_get_letohs(tvb, offset);
9055         add_fid(tvb, pinfo, tree, offset, 2, fid);
9056         offset += 2;
9057
9058         BYTE_COUNT;
9059
9060         /* buffer format */
9061         CHECK_BYTE_COUNT(1);
9062         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9063         COUNT_BYTES(1);
9064
9065         /* data len */
9066         CHECK_BYTE_COUNT(2);
9067         cnt = tvb_get_letohs(tvb, offset);
9068         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
9069         COUNT_BYTES(2);
9070
9071         /* file data */
9072         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
9073
9074         END_OF_SMB
9075
9076         return offset;
9077 }
9078
9079
9080 static const value_string print_status_vals[] = {
9081         {1,     "Held or Stopped"},
9082         {2,     "Printing"},
9083         {3,     "Awaiting print"},
9084         {4,     "In intercept"},
9085         {5,     "File had error"},
9086         {6,     "Printer error"},
9087         {0, NULL}
9088 };
9089
9090 static int
9091 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9092 {
9093         guint8 wc;
9094         guint16 bc;
9095
9096         WORD_COUNT;
9097
9098         /* max count */
9099         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
9100         offset += 2;
9101
9102         /* start index */
9103         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
9104         offset += 2;
9105
9106         BYTE_COUNT;
9107
9108         END_OF_SMB
9109
9110         return offset;
9111 }
9112
9113 static int
9114 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
9115     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
9116 {
9117         proto_item *item = NULL;
9118         proto_tree *tree = NULL;
9119         smb_info_t *si = pinfo->private_data;
9120         int fn_len;
9121         const char *fn;
9122
9123         if(parent_tree){
9124                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
9125                         "Queue entry");
9126                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
9127         }
9128
9129         /* queued time */
9130         CHECK_BYTE_COUNT_SUBR(4);
9131         offset = dissect_smb_datetime(tvb, tree, offset,
9132                 hf_smb_print_queue_date,
9133                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
9134         *bcp -= 4;
9135
9136         /* status */
9137         CHECK_BYTE_COUNT_SUBR(1);
9138         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
9139         COUNT_BYTES_SUBR(1);
9140
9141         /* spool file number */
9142         CHECK_BYTE_COUNT_SUBR(2);
9143         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
9144         COUNT_BYTES_SUBR(2);
9145
9146         /* spool file size */
9147         CHECK_BYTE_COUNT_SUBR(4);
9148         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
9149         COUNT_BYTES_SUBR(4);
9150
9151         /* reserved byte */
9152         CHECK_BYTE_COUNT_SUBR(1);
9153         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9154         COUNT_BYTES_SUBR(1);
9155
9156         /* file name */
9157         fn_len = 16;
9158         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
9159         CHECK_STRING_SUBR(fn);
9160         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
9161                 fn);
9162         COUNT_BYTES_SUBR(fn_len);
9163
9164         *trunc = FALSE;
9165         return offset;
9166 }
9167
9168 static int
9169 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9170 {
9171         guint16 cnt=0, len;
9172         guint8 wc;
9173         guint16 bc;
9174         gboolean trunc;
9175
9176         WORD_COUNT;
9177
9178         /* count */
9179         cnt = tvb_get_letohs(tvb, offset);
9180         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
9181         offset += 2;
9182
9183         /* restart index */
9184         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
9185         offset += 2;
9186
9187         BYTE_COUNT;
9188
9189         /* buffer format */
9190         CHECK_BYTE_COUNT(1);
9191         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9192         COUNT_BYTES(1);
9193
9194         /* data len */
9195         CHECK_BYTE_COUNT(2);
9196         len = tvb_get_letohs(tvb, offset);
9197         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
9198         COUNT_BYTES(2);
9199
9200         /* queue elements */
9201         while(cnt--){
9202                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
9203                     &bc, &trunc);
9204                 if (trunc)
9205                         goto endofcommand;
9206         }
9207
9208         END_OF_SMB
9209
9210         return offset;
9211 }
9212
9213
9214 static int
9215 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9216 {
9217         int name_len;
9218         guint16 bc;
9219         guint8 wc;
9220         guint16 message_len;
9221
9222         WORD_COUNT;
9223
9224         BYTE_COUNT;
9225
9226         /* buffer format */
9227         CHECK_BYTE_COUNT(1);
9228         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9229         COUNT_BYTES(1);
9230
9231         /* originator name */
9232         /* XXX - what if this runs past bc? */
9233         name_len = tvb_strsize(tvb, offset);
9234         CHECK_BYTE_COUNT(name_len);
9235         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9236             name_len, TRUE);
9237         COUNT_BYTES(name_len);
9238
9239         /* buffer format */
9240         CHECK_BYTE_COUNT(1);
9241         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9242         COUNT_BYTES(1);
9243
9244         /* destination name */
9245         /* XXX - what if this runs past bc? */
9246         name_len = tvb_strsize(tvb, offset);
9247         CHECK_BYTE_COUNT(name_len);
9248         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9249             name_len, TRUE);
9250         COUNT_BYTES(name_len);
9251
9252         /* buffer format */
9253         CHECK_BYTE_COUNT(1);
9254         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9255         COUNT_BYTES(1);
9256
9257         /* message len */
9258         CHECK_BYTE_COUNT(2);
9259         message_len = tvb_get_letohs(tvb, offset);
9260         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9261             message_len);
9262         COUNT_BYTES(2);
9263
9264         /* message */
9265         CHECK_BYTE_COUNT(message_len);
9266         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9267             TRUE);
9268         COUNT_BYTES(message_len);
9269
9270         END_OF_SMB
9271
9272         return offset;
9273 }
9274
9275 static int
9276 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9277 {
9278         int name_len;
9279         guint16 bc;
9280         guint8 wc;
9281
9282         WORD_COUNT;
9283
9284         BYTE_COUNT;
9285
9286         /* buffer format */
9287         CHECK_BYTE_COUNT(1);
9288         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9289         COUNT_BYTES(1);
9290
9291         /* originator name */
9292         /* XXX - what if this runs past bc? */
9293         name_len = tvb_strsize(tvb, offset);
9294         CHECK_BYTE_COUNT(name_len);
9295         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9296             name_len, TRUE);
9297         COUNT_BYTES(name_len);
9298
9299         /* buffer format */
9300         CHECK_BYTE_COUNT(1);
9301         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9302         COUNT_BYTES(1);
9303
9304         /* destination name */
9305         /* XXX - what if this runs past bc? */
9306         name_len = tvb_strsize(tvb, offset);
9307         CHECK_BYTE_COUNT(name_len);
9308         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9309             name_len, TRUE);
9310         COUNT_BYTES(name_len);
9311
9312         END_OF_SMB
9313
9314         return offset;
9315 }
9316
9317 static int
9318 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9319 {
9320         guint16 bc;
9321         guint8 wc;
9322
9323         WORD_COUNT;
9324
9325         /* message group ID */
9326         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
9327         offset += 2;
9328
9329         BYTE_COUNT;
9330
9331         END_OF_SMB
9332
9333         return offset;
9334 }
9335
9336 static int
9337 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9338 {
9339         guint16 bc;
9340         guint8 wc;
9341         guint16 message_len;
9342
9343         WORD_COUNT;
9344
9345         BYTE_COUNT;
9346
9347         /* buffer format */
9348         CHECK_BYTE_COUNT(1);
9349         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9350         COUNT_BYTES(1);
9351
9352         /* message len */
9353         CHECK_BYTE_COUNT(2);
9354         message_len = tvb_get_letohs(tvb, offset);
9355         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9356             message_len);
9357         COUNT_BYTES(2);
9358
9359         /* message */
9360         CHECK_BYTE_COUNT(message_len);
9361         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9362             TRUE);
9363         COUNT_BYTES(message_len);
9364
9365         END_OF_SMB
9366
9367         return offset;
9368 }
9369
9370 static int
9371 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9372 {
9373         int name_len;
9374         guint16 bc;
9375         guint8 wc;
9376
9377         WORD_COUNT;
9378
9379         BYTE_COUNT;
9380
9381         /* buffer format */
9382         CHECK_BYTE_COUNT(1);
9383         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9384         COUNT_BYTES(1);
9385
9386         /* forwarded name */
9387         /* XXX - what if this runs past bc? */
9388         name_len = tvb_strsize(tvb, offset);
9389         CHECK_BYTE_COUNT(name_len);
9390         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
9391             name_len, TRUE);
9392         COUNT_BYTES(name_len);
9393
9394         END_OF_SMB
9395
9396         return offset;
9397 }
9398
9399 static int
9400 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9401 {
9402         int name_len;
9403         guint16 bc;
9404         guint8 wc;
9405
9406         WORD_COUNT;
9407
9408         BYTE_COUNT;
9409
9410         /* buffer format */
9411         CHECK_BYTE_COUNT(1);
9412         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9413         COUNT_BYTES(1);
9414
9415         /* machine name */
9416         /* XXX - what if this runs past bc? */
9417         name_len = tvb_strsize(tvb, offset);
9418         CHECK_BYTE_COUNT(name_len);
9419         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
9420             name_len, TRUE);
9421         COUNT_BYTES(name_len);
9422
9423         END_OF_SMB
9424
9425         return offset;
9426 }
9427
9428
9429 static int
9430 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9431 {
9432         guint8  wc, cmd=0xff;
9433         guint16 andxoffset=0;
9434         guint16 bc;
9435         smb_info_t *si = pinfo->private_data;
9436         int fn_len;
9437         const char *fn;
9438
9439         WORD_COUNT;
9440
9441         /* next smb command */
9442         cmd = tvb_get_guint8(tvb, offset);
9443         if(cmd!=0xff){
9444                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9445         } else {
9446                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9447         }
9448         offset += 1;
9449
9450         /* reserved byte */
9451         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9452         offset += 1;
9453
9454         /* andxoffset */
9455         andxoffset = tvb_get_letohs(tvb, offset);
9456         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9457         offset += 2;
9458
9459         /* reserved byte */
9460         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9461         offset += 1;
9462
9463         /* file name len */
9464         fn_len = tvb_get_letohs(tvb, offset);
9465         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
9466         offset += 2;
9467
9468         /* Create flags */
9469         offset = dissect_nt_create_bits(tvb, tree, offset);
9470
9471         /* root directory fid */
9472         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
9473         offset += 4;
9474
9475         /* nt access mask */
9476         offset = dissect_smb_access_mask(tvb, tree, offset);
9477
9478         /* allocation size */
9479         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9480         offset += 8;
9481
9482         /* Extended File Attributes */
9483         offset = dissect_file_ext_attr(tvb, tree, offset);
9484
9485         /* share access */
9486         offset = dissect_nt_share_access(tvb, tree, offset);
9487
9488         /* create disposition */
9489         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
9490         offset += 4;
9491
9492         /* create options */
9493         offset = dissect_nt_create_options(tvb, tree, offset);
9494
9495         /* impersonation level */
9496         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
9497         offset += 4;
9498
9499         /* security flags */
9500         offset = dissect_nt_security_flags(tvb, tree, offset);
9501
9502         BYTE_COUNT;
9503
9504         /* file name */
9505         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9506         if (fn == NULL)
9507                 goto endofcommand;
9508         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9509                 fn);
9510         COUNT_BYTES(fn_len);
9511
9512         if (check_col(pinfo->cinfo, COL_INFO)) {
9513                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
9514         }
9515
9516         END_OF_SMB
9517
9518         /* call AndXCommand (if there are any) */
9519         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9520
9521         return offset;
9522 }
9523
9524
9525 static int
9526 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9527 {
9528         guint8  wc, cmd=0xff;
9529         guint16 andxoffset=0;
9530         guint16 bc;
9531         guint16 fid;
9532
9533         WORD_COUNT;
9534
9535         /* next smb command */
9536         cmd = tvb_get_guint8(tvb, offset);
9537         if(cmd!=0xff){
9538                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9539         } else {
9540                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9541         }
9542         offset += 1;
9543
9544         /* reserved byte */
9545         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9546         offset += 1;
9547
9548         /* andxoffset */
9549         andxoffset = tvb_get_letohs(tvb, offset);
9550         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9551         offset += 2;
9552
9553         /* oplock level */
9554         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
9555         offset += 1;
9556
9557         /* fid */
9558         fid = tvb_get_letohs(tvb, offset);
9559         add_fid(tvb, pinfo, tree, offset, 2, fid);
9560         offset += 2;
9561
9562         /* create action */
9563         /*XXX is this really the same as create disposition in the request? it looks so*/
9564         /* No, it is not. It is the same as the create action from an Open&X request ... RJS */
9565         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
9566         offset += 4;
9567
9568         /* create time */
9569         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
9570
9571         /* access time */
9572         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
9573
9574         /* last write time */
9575         offset = dissect_smb_64bit_time(tvb, tree, offset,
9576                 hf_smb_last_write_time);
9577
9578         /* last change time */
9579         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
9580
9581         /* Extended File Attributes */
9582         offset = dissect_file_ext_attr(tvb, tree, offset);
9583
9584         /* allocation size */
9585         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9586         offset += 8;
9587
9588         /* end of file */
9589         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9590         offset += 8;
9591
9592         /* File Type */
9593         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
9594         offset += 2;
9595
9596         /* IPC State */
9597         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9598
9599         /* is directory */
9600         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9601         offset += 1;
9602
9603         BYTE_COUNT;
9604
9605         END_OF_SMB
9606
9607         /* call AndXCommand (if there are any) */
9608         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9609
9610         return offset;
9611 }
9612
9613
9614 static int
9615 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9616 {
9617         guint8 wc;
9618         guint16 bc;
9619
9620         WORD_COUNT;
9621
9622         BYTE_COUNT;
9623
9624         END_OF_SMB
9625
9626         return offset;
9627 }
9628
9629 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9630    BEGIN Transaction/Transaction2 Primary and secondary requests
9631    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9632
9633
9634 const value_string trans2_cmd_vals[] = {
9635         { 0x00,         "OPEN2" },
9636         { 0x01,         "FIND_FIRST2" },
9637         { 0x02,         "FIND_NEXT2" },
9638         { 0x03,         "QUERY_FS_INFO" },
9639         { 0x04,         "SET_FS_QUOTA" },
9640         { 0x05,         "QUERY_PATH_INFO" },
9641         { 0x06,         "SET_PATH_INFO" },
9642         { 0x07,         "QUERY_FILE_INFO" },
9643         { 0x08,         "SET_FILE_INFO" },
9644         { 0x09,         "FSCTL" },
9645         { 0x0A,         "IOCTL2" },
9646         { 0x0B,         "FIND_NOTIFY_FIRST" },
9647         { 0x0C,         "FIND_NOTIFY_NEXT" },
9648         { 0x0D,         "CREATE_DIRECTORY" },
9649         { 0x0E,         "SESSION_SETUP" },
9650         { 0x10,         "GET_DFS_REFERRAL" },
9651         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
9652         { 0,    NULL }
9653 };
9654
9655 static const true_false_string tfs_tf_dtid = {
9656         "Also DISCONNECT TID",
9657         "Do NOT disconnect TID"
9658 };
9659 static const true_false_string tfs_tf_owt = {
9660         "One Way Transaction (NO RESPONSE)",
9661         "Two way transaction"
9662 };
9663
9664 static const true_false_string tfs_ff2_backup = {
9665         "Find WITH backup intent",
9666         "No backup intent"
9667 };
9668 static const true_false_string tfs_ff2_continue = {
9669         "CONTINUE search from previous position",
9670         "New search, do NOT continue from previous position"
9671 };
9672 static const true_false_string tfs_ff2_resume = {
9673         "Return RESUME keys",
9674         "Do NOT return resume keys"
9675 };
9676 static const true_false_string tfs_ff2_close_eos = {
9677         "CLOSE search if END OF SEARCH is reached",
9678         "Do NOT close search if end of search reached"
9679 };
9680 static const true_false_string tfs_ff2_close = {
9681         "CLOSE search after this request",
9682         "Do NOT close search after this request"
9683 };
9684
9685 /* used by
9686    TRANS2_FIND_FIRST2
9687 */
9688 static const value_string ff2_il_vals[] = {
9689         { 1,            "Info Standard"},
9690         { 2,            "Info Query EA Size"},
9691         { 3,            "Info Query EAs From List"},
9692         { 0x0101,       "Find File Directory Info"},
9693         { 0x0102,       "Find File Full Directory Info"},
9694         { 0x0103,       "Find File Names Info"},
9695         { 0x0104,       "Find File Both Directory Info"},
9696         { 0x0202,       "Find File UNIX"},
9697         {0, NULL}
9698 };
9699
9700 /* values used by :
9701         TRANS2_QUERY_PATH_INFORMATION
9702         TRANS2_QUERY_FILE_INFORMATION
9703 */
9704 static const value_string qpi_loi_vals[] = {
9705         { 1,            "Info Standard"},
9706         { 2,            "Info Query EA Size"},
9707         { 3,            "Info Query EAs From List"},
9708         { 4,            "Info Query All EAs"},
9709         { 6,            "Info Is Name Valid"},
9710         { 0x0101,       "Query File Basic Info"},
9711         { 0x0102,       "Query File Standard Info"},
9712         { 0x0103,       "Query File EA Info"},
9713         { 0x0104,       "Query File Name Info"},
9714         { 0x0107,       "Query File All Info"},
9715         { 0x0108,       "Query File Alt Name Info"},
9716         { 0x0109,       "Query File Stream Info"},
9717         { 0x010b,       "Query File Compression Info"},
9718         { 0x0200,       "Query File Unix Basic"},
9719         { 0x0201,       "Query File Unix Link"},
9720         { 1004,         "Query File Basic Info"},
9721         { 1005,         "Query File Standard Info"},
9722         { 1006,         "Query File Internal Info"},
9723         { 1007,         "Query File EA Info"},
9724         { 1009,         "Query File Name Info"},
9725         { 1010,         "Query File Rename Info"},
9726         { 1011,         "Query File Link Info"},
9727         { 1012,         "Query File Names Info"},
9728         { 1013,         "Query File Disposition Info"},
9729         { 1014,         "Query File Position Info"},
9730         { 1015,         "Query File Full EA Info"},
9731         { 1016,         "Query File Mode Info"},
9732         { 1017,         "Query File Alignment Info"},
9733         { 1018,         "Query File All Info"},
9734         { 1019,         "Query File Allocation Info"},
9735         { 1020,         "Query File End of File Info"},
9736         { 1021,         "Query File Alt Name Info"},
9737         { 1022,         "Query File Stream Info"},
9738         { 1023,         "Query File Pipe Info"},
9739         { 1024,         "Query File Pipe Local Info"},
9740         { 1025,         "Query File Pipe Remote Info"},
9741         { 1026,         "Query File Mailslot Query Info"},
9742         { 1027,         "Query File Mailslot Set Info"},
9743         { 1028,         "Query File Compression Info"},
9744         { 1029,         "Query File ObjectID Info"},
9745         { 1030,         "Query File Completion Info"},
9746         { 1031,         "Query File Move Cluster Info"},
9747         { 1032,         "Query File Quota Info"},
9748         { 1033,         "Query File Reparsepoint Info"},
9749         { 1034,         "Query File Network Open Info"},
9750         { 1035,         "Query File Attribute Tag Info"},
9751         { 1036,         "Query File Tracking Info"},
9752         { 1037,         "Query File Maximum Info"},
9753         {0, NULL}
9754 };
9755
9756 /* values used by :
9757         TRANS2_SET_PATH_INFORMATION
9758         TRANS2_SET_FILE_INFORMATION
9759         (the SNIA CIFS spec lists some only for TRANS2_SET_FILE_INFORMATION,
9760         but I'm assuming they apply to TRANS2_SET_PATH_INFORMATION as
9761         well; note that they're different from the QUERY_PATH_INFORMATION
9762         and QUERY_FILE_INFORMATION values!)
9763 */
9764 static const value_string spi_loi_vals[] = {
9765         { 1,            "Info Standard"},
9766         { 2,            "Info Query EA Size"},
9767         { 4,            "Info Query All EAs"},
9768         { 0x0101,       "Set File Basic Info"},
9769         { 0x0102,       "Set File Disposition Info"},
9770         { 0x0103,       "Set File Allocation Info"},
9771         { 0x0104,       "Set File End Of File Info"},
9772         { 0x0200,       "Set File Unix Basic"},
9773         { 0x0201,       "Set File Unix Link"},
9774         { 0x0202,       "Set File Unix HardLink"},
9775         { 1004,         "Set File Basic Info"},
9776         { 1010,         "Set Rename Information"},
9777         { 1013,         "Set Disposition Information"},
9778         { 1014,         "Set Position Information"},
9779         { 1016,         "Set Mode Information"},
9780         { 1019,         "Set Allocation Information"},
9781         { 1020,         "Set EOF Information"},
9782         { 1023,         "Set File Pipe Information"},
9783         { 1025,         "Set File Pipe Remote Information"},
9784         { 1029,         "Set Copy On Write Information"},
9785         { 1032,         "Set OLE Class ID Information"},
9786         { 1039,         "Set Inherit Context Index Information"},
9787         { 1040,         "Set OLE Information (?)"},
9788         {0, NULL}
9789 };
9790
9791 static const value_string qfsi_vals[] = {
9792         { 1,            "Info Allocation"},
9793         { 2,            "Info Volume"},
9794         { 0x0101,       "Query FS Label Info"},
9795         { 0x0102,       "Query FS Volume Info"},
9796         { 0x0103,       "Query FS Size Info"},
9797         { 0x0104,       "Query FS Device Info"},
9798         { 0x0105,       "Query FS Attribute Info"},
9799         { 0x0200,       "Unix Query FS Info"},
9800         { 0x0301,       "Mac Query FS Info"},
9801         { 1001,         "Query FS Label Info"},
9802         { 1002,         "Query FS Volume Info"},
9803         { 1003,         "Query FS Size Info"},
9804         { 1004,         "Query FS Device Info"},
9805         { 1005,         "Query FS Attribute Info"},
9806         { 1006,         "Query FS Quota Info"},
9807         { 1007,         "Query Full FS Size Info"},
9808         { 1008,         "Object ID Information"},
9809         {0, NULL}
9810 };
9811
9812 static const value_string nt_rename_vals[] = {
9813         { 0x0103,       "Create Hard Link"},
9814         {0, NULL}
9815 };
9816
9817
9818 static const value_string delete_pending_vals[] = {
9819         {0,     "Normal, no pending delete"},
9820         {1,     "This object has DELETE PENDING"},
9821         {0, NULL}
9822 };
9823
9824 static const value_string alignment_vals[] = {
9825         {0,     "Byte alignment"},
9826         {1,     "Word (16bit) alignment"},
9827         {3,     "Long (32bit) alignment"},
9828         {7,     "8 byte boundary alignment"},
9829         {0x0f,  "16 byte boundary alignment"},
9830         {0x1f,  "32 byte boundary alignment"},
9831         {0x3f,  "64 byte boundary alignment"},
9832         {0x7f,  "128 byte boundary alignment"},
9833         {0xff,  "256 byte boundary alignment"},
9834         {0x1ff, "512 byte boundary alignment"},
9835         {0, NULL}
9836 };
9837
9838 static const true_false_string tfs_marked_for_deletion = {
9839         "File is MARKED FOR DELETION",
9840         "File is NOT marked for deletion"
9841 };
9842
9843 static const true_false_string tfs_get_dfs_server_hold_storage = {
9844         "Referral SERVER HOLDS STORAGE for the file",
9845         "Referral server does NOT hold storage for the file"
9846 };
9847 static const true_false_string tfs_get_dfs_fielding = {
9848         "The server in referral is FIELDING CAPABLE",
9849         "The server in referrals is NOT fielding capable"
9850 };
9851
9852 static const true_false_string tfs_dfs_referral_flags_strip = {
9853         "STRIP off pathconsumed characters before submitting",
9854         "Do NOT strip off any characters"
9855 };
9856
9857 static const value_string dfs_referral_server_type_vals[] = {
9858         {0,     "Don't know"},
9859         {1,     "SMB Server"},
9860         {2,     "Netware Server"},
9861         {3,     "Domain Server"},
9862         {0, NULL}
9863 };
9864
9865
9866 static const true_false_string tfs_device_char_removable = {
9867         "This is a REMOVABLE device",
9868         "This is NOT a removable device"
9869 };
9870 static const true_false_string tfs_device_char_read_only = {
9871         "This is a READ-ONLY device",
9872         "This is NOT a read-only device"
9873 };
9874 static const true_false_string tfs_device_char_floppy = {
9875         "This is a FLOPPY DISK device",
9876         "This is NOT a floppy disk device"
9877 };
9878 static const true_false_string tfs_device_char_write_once = {
9879         "This is a WRITE-ONCE device",
9880         "This is NOT a write-once device"
9881 };
9882 static const true_false_string tfs_device_char_remote = {
9883         "This is a REMOTE device",
9884         "This is NOT a remote device"
9885 };
9886 static const true_false_string tfs_device_char_mounted = {
9887         "This device is MOUNTED",
9888         "This device is NOT mounted"
9889 };
9890 static const true_false_string tfs_device_char_virtual = {
9891         "This is a VIRTUAL device",
9892         "This is NOT a virtual device"
9893 };
9894
9895
9896 static const true_false_string tfs_fs_attr_css = {
9897         "This FS supports CASE SENSITIVE SEARCHes",
9898         "This FS does NOT support case sensitive searches"
9899 };
9900 static const true_false_string tfs_fs_attr_cpn = {
9901         "This FS supports CASE PRESERVED NAMES",
9902         "This FS does NOT support case preserved names"
9903 };
9904 static const true_false_string tfs_fs_attr_pacls = {
9905         "This FS supports PERSISTENT ACLs",
9906         "This FS does NOT support persistent acls"
9907 };
9908 static const true_false_string tfs_fs_attr_fc = {
9909         "This FS supports COMPRESSED FILES",
9910         "This FS does NOT support compressed files"
9911 };
9912 static const true_false_string tfs_fs_attr_vq = {
9913         "This FS supports VOLUME QUOTAS",
9914         "This FS does NOT support volume quotas"
9915 };
9916 static const true_false_string tfs_fs_attr_dim = {
9917         "This FS is on a MOUNTED DEVICE",
9918         "This FS is NOT on a mounted device"
9919 };
9920 static const true_false_string tfs_fs_attr_vic = {
9921         "This FS is on a COMPRESSED VOLUME",
9922         "This FS is NOT on a compressed volume"
9923 };
9924
9925 #define FF2_RESUME      0x0004
9926
9927 static int
9928 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9929 {
9930         guint16 mask;
9931         proto_item *item = NULL;
9932         proto_tree *tree = NULL;
9933         smb_info_t *si;
9934         smb_transact2_info_t *t2i;
9935
9936         mask = tvb_get_letohs(tvb, offset);
9937
9938         si = (smb_info_t *)pinfo->private_data;
9939         if (si->sip != NULL) {
9940                 t2i = si->sip->extra_info;
9941                 if (t2i != NULL) {
9942                         if (!pinfo->fd->flags.visited)
9943                                 t2i->resume_keys = (mask & FF2_RESUME);
9944                 }
9945         }
9946
9947         if(parent_tree){
9948                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9949                         "Flags: 0x%04x", mask);
9950                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
9951         }
9952
9953         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
9954                 tvb, offset, 2, mask);
9955         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
9956                 tvb, offset, 2, mask);
9957         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
9958                 tvb, offset, 2, mask);
9959         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
9960                 tvb, offset, 2, mask);
9961         proto_tree_add_boolean(tree, hf_smb_ff2_close,
9962                 tvb, offset, 2, mask);
9963
9964         offset += 2;
9965
9966         return offset;
9967 }
9968
9969 #if 0
9970 static int
9971 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9972 {
9973         guint16 mask;
9974         proto_item *item = NULL;
9975         proto_tree *tree = NULL;
9976
9977         mask = tvb_get_letohs(tvb, offset);
9978
9979         if(parent_tree){
9980                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9981                         "IO Flag: 0x%04x", mask);
9982                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
9983         }
9984
9985         proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
9986                 tvb, offset, 2, mask);
9987         proto_tree_add_boolean(tree, hf_smb_sfi_caching,
9988                 tvb, offset, 2, mask);
9989
9990         offset += 2;
9991
9992         return offset;
9993 }
9994 #endif
9995
9996 static int
9997 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
9998     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
9999 {
10000         proto_item *item = NULL;
10001         proto_tree *tree = NULL;
10002         smb_info_t *si;
10003         smb_transact2_info_t *t2i;
10004         int fn_len;
10005         const char *fn;
10006
10007         si = (smb_info_t *)pinfo->private_data;
10008         if (si->sip != NULL)
10009                 t2i = si->sip->extra_info;
10010         else
10011                 t2i = NULL;
10012
10013         if(parent_tree){
10014                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
10015                                 "%s Parameters",
10016                                 val_to_str(subcmd, trans2_cmd_vals,
10017                                            "Unknown (0x%02x)"));
10018                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
10019         }
10020
10021         switch(subcmd){
10022         case 0x00:      /*TRANS2_OPEN2*/
10023                 /* open flags */
10024                 CHECK_BYTE_COUNT_TRANS(2);
10025                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
10026                 bc -= 2;
10027
10028                 /* desired access */
10029                 CHECK_BYTE_COUNT_TRANS(2);
10030                 offset = dissect_access(tvb, tree, offset, "Desired");
10031                 bc -= 2;
10032
10033                 /* Search Attributes */
10034                 CHECK_BYTE_COUNT_TRANS(2);
10035                 offset = dissect_search_attributes(tvb, tree, offset);
10036                 bc -= 2;
10037
10038                 /* File Attributes */
10039                 CHECK_BYTE_COUNT_TRANS(2);
10040                 offset = dissect_file_attributes(tvb, tree, offset, 2);
10041                 bc -= 2;
10042
10043                 /* create time */
10044                 CHECK_BYTE_COUNT_TRANS(4);
10045                 offset = dissect_smb_datetime(tvb, tree, offset,
10046                         hf_smb_create_time,
10047                         hf_smb_create_dos_date, hf_smb_create_dos_time,
10048                         TRUE);
10049                 bc -= 4;
10050
10051                 /* open function */
10052                 CHECK_BYTE_COUNT_TRANS(2);
10053                 offset = dissect_open_function(tvb, tree, offset);
10054                 bc -= 2;
10055
10056                 /* allocation size */
10057                 CHECK_BYTE_COUNT_TRANS(4);
10058                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10059                 COUNT_BYTES_TRANS(4);
10060
10061                 /* 10 reserved bytes */
10062                 CHECK_BYTE_COUNT_TRANS(10);
10063                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
10064                 COUNT_BYTES_TRANS(10);
10065
10066                 /* file name */
10067                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10068                 CHECK_STRING_TRANS(fn);
10069                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10070                         fn);
10071                 COUNT_BYTES_TRANS(fn_len);
10072
10073                 if (check_col(pinfo->cinfo, COL_INFO)) {
10074                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10075                         fn);
10076                 }
10077                 break;
10078         case 0x01:      /*TRANS2_FIND_FIRST2*/
10079                 /* Search Attributes */
10080                 CHECK_BYTE_COUNT_TRANS(2);
10081                 offset = dissect_search_attributes(tvb, tree, offset);
10082                 bc -= 2;
10083
10084                 /* search count */
10085                 CHECK_BYTE_COUNT_TRANS(2);
10086                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10087                 COUNT_BYTES_TRANS(2);
10088
10089                 /* Find First2 flags */
10090                 CHECK_BYTE_COUNT_TRANS(2);
10091                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10092                 bc -= 2;
10093
10094                 /* Find First2 information level */
10095                 CHECK_BYTE_COUNT_TRANS(2);
10096                 si->info_level = tvb_get_letohs(tvb, offset);
10097                 if (!pinfo->fd->flags.visited)
10098                         t2i->info_level = si->info_level;
10099                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10100                 COUNT_BYTES_TRANS(2);
10101
10102                 /* storage type */
10103                 CHECK_BYTE_COUNT_TRANS(4);
10104                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
10105                 COUNT_BYTES_TRANS(4);
10106
10107                 /* search pattern */
10108                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10109                 CHECK_STRING_TRANS(fn);
10110                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
10111                         fn);
10112                 COUNT_BYTES_TRANS(fn_len);
10113
10114                 if (check_col(pinfo->cinfo, COL_INFO)) {
10115                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
10116                         fn);
10117                 }
10118
10119                 break;
10120         case 0x02:      /*TRANS2_FIND_NEXT2*/
10121                 /* sid */
10122                 CHECK_BYTE_COUNT_TRANS(2);
10123                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
10124                 COUNT_BYTES_TRANS(2);
10125
10126                 /* search count */
10127                 CHECK_BYTE_COUNT_TRANS(2);
10128                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10129                 COUNT_BYTES_TRANS(2);
10130
10131                 /* Find First2 information level */
10132                 CHECK_BYTE_COUNT_TRANS(2);
10133                 si->info_level = tvb_get_letohs(tvb, offset);
10134                 if (!pinfo->fd->flags.visited)
10135                         t2i->info_level = si->info_level;
10136                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10137                 COUNT_BYTES_TRANS(2);
10138
10139                 /* resume key */
10140                 CHECK_BYTE_COUNT_TRANS(4);
10141                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
10142                 COUNT_BYTES_TRANS(4);
10143
10144                 /* Find First2 flags */
10145                 CHECK_BYTE_COUNT_TRANS(2);
10146                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10147                 bc -= 2;
10148
10149                 /* file name */
10150                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10151                 CHECK_STRING_TRANS(fn);
10152                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10153                         fn);
10154                 COUNT_BYTES_TRANS(fn_len);
10155
10156                 if (check_col(pinfo->cinfo, COL_INFO)) {
10157                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
10158                         fn);
10159                 }
10160
10161                 break;
10162         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10163                 /* level of interest */
10164                 CHECK_BYTE_COUNT_TRANS(2);
10165                 si->info_level = tvb_get_letohs(tvb, offset);
10166                 if (!pinfo->fd->flags.visited)
10167                         t2i->info_level = si->info_level;
10168                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
10169                 COUNT_BYTES_TRANS(2);
10170
10171                 if (check_col(pinfo->cinfo, COL_INFO))
10172                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
10173                                         val_to_str(si->info_level, qfsi_vals, 
10174                                                    "Unknown (0x%02x)"));
10175
10176                 break;
10177         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10178                 /* level of interest */
10179                 CHECK_BYTE_COUNT_TRANS(2);
10180                 si->info_level = tvb_get_letohs(tvb, offset);
10181                 if (!pinfo->fd->flags.visited)
10182                         t2i->info_level = si->info_level;
10183                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10184                 COUNT_BYTES_TRANS(2);
10185
10186                 if (check_col(pinfo->cinfo, COL_INFO)) {
10187                         col_append_fstr(
10188                                 pinfo->cinfo, COL_INFO, ", %s", 
10189                                 val_to_str(si->info_level, qpi_loi_vals, 
10190                                            "Unknown (%u)"));
10191                 }
10192
10193                 /* 4 reserved bytes */
10194                 CHECK_BYTE_COUNT_TRANS(4);
10195                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10196                 COUNT_BYTES_TRANS(4);
10197
10198                 /* file name */
10199                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10200                 CHECK_STRING_TRANS(fn);
10201                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10202                         fn);
10203                 COUNT_BYTES_TRANS(fn_len);
10204
10205                 if (check_col(pinfo->cinfo, COL_INFO)) {
10206                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10207                         fn);
10208                 }
10209
10210                 break;
10211         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10212                 /* level of interest */
10213                 CHECK_BYTE_COUNT_TRANS(2);
10214                 si->info_level = tvb_get_letohs(tvb, offset);
10215                 if (!pinfo->fd->flags.visited)
10216                         t2i->info_level = si->info_level;
10217                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10218                 COUNT_BYTES_TRANS(2);
10219
10220                 /* 4 reserved bytes */
10221                 CHECK_BYTE_COUNT_TRANS(4);
10222                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10223                 COUNT_BYTES_TRANS(4);
10224
10225                 /* file name */
10226                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10227                 CHECK_STRING_TRANS(fn);
10228                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10229                         fn);
10230                 COUNT_BYTES_TRANS(fn_len);
10231
10232                 if (check_col(pinfo->cinfo, COL_INFO)) {
10233                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10234                         fn);
10235                 }
10236
10237                 break;
10238         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
10239                 guint16 fid;
10240
10241                 /* fid */
10242                 CHECK_BYTE_COUNT_TRANS(2);
10243                 fid = tvb_get_letohs(tvb, offset);
10244                 add_fid(tvb, pinfo, tree, offset, 2, fid);
10245                 COUNT_BYTES_TRANS(2);
10246
10247                 /* level of interest */
10248                 CHECK_BYTE_COUNT_TRANS(2);
10249                 si->info_level = tvb_get_letohs(tvb, offset);
10250                 if (!pinfo->fd->flags.visited)
10251                         t2i->info_level = si->info_level;
10252                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10253                 COUNT_BYTES_TRANS(2);
10254
10255                 if (check_col(pinfo->cinfo, COL_INFO)) {
10256                         col_append_fstr(
10257                                 pinfo->cinfo, COL_INFO, ", %s", 
10258                                 val_to_str(si->info_level, qpi_loi_vals, 
10259                                            "Unknown (%u)"));
10260                 }
10261
10262                 break;
10263         }
10264         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
10265                 guint16 fid;
10266
10267                 /* fid */
10268                 CHECK_BYTE_COUNT_TRANS(2);
10269                 fid = tvb_get_letohs(tvb, offset);
10270                 add_fid(tvb, pinfo, tree, offset, 2, fid);
10271                 COUNT_BYTES_TRANS(2);
10272
10273                 /* level of interest */
10274                 CHECK_BYTE_COUNT_TRANS(2);
10275                 si->info_level = tvb_get_letohs(tvb, offset);
10276                 if (!pinfo->fd->flags.visited)
10277                         t2i->info_level = si->info_level;
10278                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10279                 COUNT_BYTES_TRANS(2);
10280
10281 #if 0
10282                 /*
10283                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10284                  * Extensions Version 3.0, Document Version 1.11,
10285                  * July 19, 1990" says this is I/O flags, but it's
10286                  * reserved in the SNIA spec, and some clients appear
10287                  * to leave junk in it.
10288                  *
10289                  * Is this some field used only if a particular
10290                  * dialect was negotiated, so that clients can feel
10291                  * safe not setting it if they haven't negotiated that
10292                  * dialect?  Or do the (non-OS/2) clients simply not care
10293                  * about that particular OS/2-oriented dialect?
10294                  */
10295
10296                 /* IO Flag */
10297                 CHECK_BYTE_COUNT_TRANS(2);
10298                 offset = dissect_sfi_ioflag(tvb, tree, offset);
10299                 bc -= 2;
10300 #else
10301                 /* 2 reserved bytes */
10302                 CHECK_BYTE_COUNT_TRANS(2);
10303                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10304                 COUNT_BYTES_TRANS(2);
10305 #endif
10306
10307                 break;
10308         }
10309         case 0x09:      /*TRANS2_FSCTL*/
10310                 /* this call has no parameter block in the request */
10311
10312                 /*
10313                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10314                  * Extensions Version 3.0, Document Version 1.11,
10315                  * July 19, 1990" says this this contains a
10316                  * "File system specific parameter block".  (That means
10317                  * we may not be able to dissect it in any case.)
10318                  */
10319                 break;
10320         case 0x0a:      /*TRANS2_IOCTL2*/
10321                 /* this call has no parameter block in the request */
10322
10323                 /*
10324                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10325                  * Extensions Version 3.0, Document Version 1.11,
10326                  * July 19, 1990" says this this contains a
10327                  * "Device/function specific parameter block".  (That
10328                  * means we may not be able to dissect it in any case.)
10329                  */
10330                 break;
10331         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
10332                 /* Search Attributes */
10333                 CHECK_BYTE_COUNT_TRANS(2);
10334                 offset = dissect_search_attributes(tvb, tree, offset);
10335                 bc -= 2;
10336
10337                 /* Number of changes to wait for */
10338                 CHECK_BYTE_COUNT_TRANS(2);
10339                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10340                 COUNT_BYTES_TRANS(2);
10341
10342                 /* Find Notify information level */
10343                 CHECK_BYTE_COUNT_TRANS(2);
10344                 si->info_level = tvb_get_letohs(tvb, offset);
10345                 if (!pinfo->fd->flags.visited)
10346                         t2i->info_level = si->info_level;
10347                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
10348                 COUNT_BYTES_TRANS(2);
10349
10350                 /* 4 reserved bytes */
10351                 CHECK_BYTE_COUNT_TRANS(4);
10352                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10353                 COUNT_BYTES_TRANS(4);
10354
10355                 /* file name */
10356                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10357                 CHECK_STRING_TRANS(fn);
10358                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10359                         fn);
10360                 COUNT_BYTES_TRANS(fn_len);
10361
10362                 if (check_col(pinfo->cinfo, COL_INFO)) {
10363                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10364                         fn);
10365                 }
10366
10367                 break;
10368         }
10369         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
10370                 /* Monitor handle */
10371                 CHECK_BYTE_COUNT_TRANS(2);
10372                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
10373                 COUNT_BYTES_TRANS(2);
10374
10375                 /* Number of changes to wait for */
10376                 CHECK_BYTE_COUNT_TRANS(2);
10377                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10378                 COUNT_BYTES_TRANS(2);
10379
10380                 break;
10381         }
10382         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10383                 /* 4 reserved bytes */
10384                 CHECK_BYTE_COUNT_TRANS(4);
10385                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10386                 COUNT_BYTES_TRANS(4);
10387
10388                 /* dir name */
10389                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
10390                         FALSE, FALSE, &bc);
10391                 CHECK_STRING_TRANS(fn);
10392                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
10393                         fn);
10394                 COUNT_BYTES_TRANS(fn_len);
10395
10396                 if (check_col(pinfo->cinfo, COL_INFO)) {
10397                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
10398                         fn);
10399                 }
10400                 break;
10401         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10402                 /* XXX unknown structure*/
10403                 break;
10404         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10405                 /* referral level */
10406                 CHECK_BYTE_COUNT_TRANS(2);
10407                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
10408                 COUNT_BYTES_TRANS(2);
10409
10410                 /* file name */
10411                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10412                 CHECK_STRING_TRANS(fn);
10413                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10414                         fn);
10415                 COUNT_BYTES_TRANS(fn_len);
10416
10417                 if (check_col(pinfo->cinfo, COL_INFO)) {
10418                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10419                         fn);
10420                 }
10421
10422                 break;
10423         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10424                 /* file name */
10425                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10426                 CHECK_STRING_TRANS(fn);
10427                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10428                         fn);
10429                 COUNT_BYTES_TRANS(fn_len);
10430
10431                 if (check_col(pinfo->cinfo, COL_INFO)) {
10432                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10433                         fn);
10434                 }
10435
10436                 break;
10437         }
10438
10439         /* ooops there were data we didnt know how to process */
10440         if(bc != 0){
10441                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, bc, TRUE);
10442                 offset += bc;
10443         }
10444
10445         return offset;
10446 }
10447
10448 /*
10449  * XXX - just use "dissect_connect_flags()" here?
10450  */
10451 static guint16
10452 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10453 {
10454         guint16 mask;
10455         proto_item *item = NULL;
10456         proto_tree *tree = NULL;
10457
10458         mask = tvb_get_letohs(tvb, offset);
10459
10460         if(parent_tree){
10461                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10462                         "Flags: 0x%04x", mask);
10463                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
10464         }
10465
10466         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
10467                 tvb, offset, 2, mask);
10468         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
10469                 tvb, offset, 2, mask);
10470
10471         return mask;
10472 }
10473
10474
10475 static int
10476 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10477 {
10478         guint16 mask;
10479         proto_item *item = NULL;
10480         proto_tree *tree = NULL;
10481
10482         mask = tvb_get_letohs(tvb, offset);
10483
10484         if(parent_tree){
10485                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10486                         "Flags: 0x%04x", mask);
10487                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
10488         }
10489
10490         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
10491                 tvb, offset, 2, mask);
10492         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
10493                 tvb, offset, 2, mask);
10494
10495         offset += 2;
10496         return offset;
10497 }
10498
10499 static int
10500 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10501 {
10502         guint16 mask;
10503         proto_item *item = NULL;
10504         proto_tree *tree = NULL;
10505
10506         mask = tvb_get_letohs(tvb, offset);
10507
10508         if(parent_tree){
10509                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10510                         "Flags: 0x%04x", mask);
10511                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
10512         }
10513
10514         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
10515                 tvb, offset, 2, mask);
10516
10517         offset += 2;
10518
10519         return offset;
10520 }
10521
10522
10523 /* dfs inconsistency data  (4.4.2)
10524 */
10525 static int
10526 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
10527     proto_tree *tree, int offset, guint16 *bcp)
10528 {
10529         smb_info_t *si = pinfo->private_data;
10530         int fn_len;
10531         const char *fn;
10532
10533         /*XXX shouldn this data hold version and size? unclear from doc*/
10534         /* referral version */
10535         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10536         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
10537         COUNT_BYTES_TRANS_SUBR(2);
10538
10539         /* referral size */
10540         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10541         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
10542         COUNT_BYTES_TRANS_SUBR(2);
10543
10544         /* referral server type */
10545         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10546         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10547         COUNT_BYTES_TRANS_SUBR(2);
10548
10549         /* referral flags */
10550         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10551         offset = dissect_dfs_referral_flags(tvb, tree, offset);
10552         *bcp -= 2;
10553
10554         /* node name */
10555         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10556         CHECK_STRING_TRANS_SUBR(fn);
10557         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10558                 fn);
10559         COUNT_BYTES_TRANS_SUBR(fn_len);
10560
10561         return offset;
10562 }
10563
10564 /* get dfs referral data  (4.4.1)
10565 */
10566 static int
10567 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
10568     proto_tree *tree, int offset, guint16 *bcp)
10569 {
10570         smb_info_t *si = pinfo->private_data;
10571         guint16 numref;
10572         guint16 refsize;
10573         guint16 pathoffset;
10574         guint16 altpathoffset;
10575         guint16 nodeoffset;
10576         int fn_len;
10577         int stroffset;
10578         int offsetoffset;
10579         guint16 save_bc;
10580         const char *fn;
10581         int unklen;
10582         int ucstring_end;
10583         int ucstring_len;
10584
10585         /* path consumed */
10586         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10587         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
10588         COUNT_BYTES_TRANS_SUBR(2);
10589
10590         /* num referrals */
10591         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10592         numref = tvb_get_letohs(tvb, offset);
10593         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
10594         COUNT_BYTES_TRANS_SUBR(2);
10595
10596         /* get dfs flags */
10597         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10598         offset = dissect_get_dfs_flags(tvb, tree, offset);
10599         *bcp -= 2;
10600
10601         /* XXX - in at least one capture there appears to be 2 bytes
10602            of stuff after the Dfs flags, perhaps so that the header
10603            in front of the referral list is a multiple of 4 bytes long. */
10604         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10605         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
10606         COUNT_BYTES_TRANS_SUBR(2);
10607
10608         /* if there are any referrals */
10609         if(numref){
10610                 proto_item *ref_item = NULL;
10611                 proto_tree *ref_tree = NULL;
10612                 int old_offset=offset;
10613
10614                 if(tree){
10615                         ref_item = proto_tree_add_text(tree,
10616                                 tvb, offset, *bcp, "Referrals");
10617                         ref_tree = proto_item_add_subtree(ref_item,
10618                                 ett_smb_dfs_referrals);
10619                 }
10620                 ucstring_end = -1;
10621
10622                 while(numref--){
10623                         proto_item *ri = NULL;
10624                         proto_tree *rt = NULL;
10625                         int old_offset=offset;
10626                         guint16 version;
10627
10628                         if(tree){
10629                                 ri = proto_tree_add_text(ref_tree,
10630                                         tvb, offset, *bcp, "Referral");
10631                                 rt = proto_item_add_subtree(ri,
10632                                         ett_smb_dfs_referral);
10633                         }
10634
10635                         /* referral version */
10636                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10637                         version = tvb_get_letohs(tvb, offset);
10638                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
10639                                 tvb, offset, 2, version);
10640                         COUNT_BYTES_TRANS_SUBR(2);
10641
10642                         /* referral size */
10643                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10644                         refsize = tvb_get_letohs(tvb, offset);
10645                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
10646                         COUNT_BYTES_TRANS_SUBR(2);
10647
10648                         /* referral server type */
10649                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10650                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10651                         COUNT_BYTES_TRANS_SUBR(2);
10652
10653                         /* referral flags */
10654                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10655                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
10656                         *bcp -= 2;
10657
10658                         switch(version){
10659
10660                         case 1:
10661                                 /* node name */
10662                                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10663                                 CHECK_STRING_TRANS_SUBR(fn);
10664                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10665                                         fn);
10666                                 COUNT_BYTES_TRANS_SUBR(fn_len);
10667                                 break;
10668
10669                         case 2:
10670                         case 3: /* XXX - like version 2, but not identical;
10671                                    seen in a capture, but the format isn't
10672                                    documented */
10673                                 /* proximity */
10674                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10675                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
10676                                 COUNT_BYTES_TRANS_SUBR(2);
10677
10678                                 /* ttl */
10679                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10680                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
10681                                 COUNT_BYTES_TRANS_SUBR(2);
10682
10683                                 /* path offset */
10684                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10685                                 pathoffset = tvb_get_letohs(tvb, offset);
10686                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
10687                                 COUNT_BYTES_TRANS_SUBR(2);
10688
10689                                 /* alt path offset */
10690                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10691                                 altpathoffset = tvb_get_letohs(tvb, offset);
10692                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
10693                                 COUNT_BYTES_TRANS_SUBR(2);
10694
10695                                 /* node offset */
10696                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10697                                 nodeoffset = tvb_get_letohs(tvb, offset);
10698                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
10699                                 COUNT_BYTES_TRANS_SUBR(2);
10700
10701                                 /* path */
10702                                 if (pathoffset != 0) {
10703                                         stroffset = old_offset + pathoffset;
10704                                         offsetoffset = stroffset - offset;
10705                                         if (offsetoffset > 0 &&
10706                                             *bcp > offsetoffset) {
10707                                                 save_bc = *bcp;
10708                                                 *bcp -= offsetoffset;
10709                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10710                                                 CHECK_STRING_TRANS_SUBR(fn);
10711                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
10712                                                         fn);
10713                                                 stroffset += fn_len;
10714                                                 if (ucstring_end < stroffset)
10715                                                         ucstring_end = stroffset;
10716                                                 *bcp = save_bc;
10717                                         }
10718                                 }
10719
10720                                 /* alt path */
10721                                 if (altpathoffset != 0) {
10722                                         stroffset = old_offset + altpathoffset;
10723                                         offsetoffset = stroffset - offset;
10724                                         if (offsetoffset > 0 &&
10725                                             *bcp > offsetoffset) {
10726                                                 save_bc = *bcp;
10727                                                 *bcp -= offsetoffset;
10728                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10729                                                 CHECK_STRING_TRANS_SUBR(fn);
10730                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
10731                                                         fn);
10732                                                 stroffset += fn_len;
10733                                                 if (ucstring_end < stroffset)
10734                                                         ucstring_end = stroffset;
10735                                                 *bcp = save_bc;
10736                                         }
10737                                 }
10738
10739                                 /* node */
10740                                 if (nodeoffset != 0) {
10741                                         stroffset = old_offset + nodeoffset;
10742                                         offsetoffset = stroffset - offset;
10743                                         if (offsetoffset > 0 &&
10744                                             *bcp > offsetoffset) {
10745                                                 save_bc = *bcp;
10746                                                 *bcp -= offsetoffset;
10747                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10748                                                 CHECK_STRING_TRANS_SUBR(fn);
10749                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
10750                                                         fn);
10751                                                 stroffset += fn_len;
10752                                                 if (ucstring_end < stroffset)
10753                                                         ucstring_end = stroffset;
10754                                                 *bcp = save_bc;
10755                                         }
10756                                 }
10757                                 break;
10758                         }
10759
10760                         /*
10761                          * Show anything beyond the length of the referral
10762                          * as unknown data.
10763                          */
10764                         unklen = (old_offset + refsize) - offset;
10765                         if (unklen < 0) {
10766                                 /*
10767                                  * XXX - the length is bogus.
10768                                  */
10769                                 unklen = 0;
10770                         }
10771                         if (unklen != 0) {
10772                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
10773                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
10774                                     offset, unklen, TRUE);
10775                                 COUNT_BYTES_TRANS_SUBR(unklen);
10776                         }
10777
10778                         proto_item_set_len(ri, offset-old_offset);
10779                 }
10780
10781                 /*
10782                  * Treat the offset past the end of the last Unicode
10783                  * string after the referrals (if any) as the last
10784                  * offset.
10785                  */
10786                 if (ucstring_end > offset) {
10787                         ucstring_len = ucstring_end - offset;
10788                         if (*bcp < ucstring_len)
10789                                 ucstring_len = *bcp;
10790                         offset += ucstring_len;
10791                         *bcp -= ucstring_len;
10792                 }
10793                 proto_item_set_len(ref_item, offset-old_offset);
10794         }
10795
10796         return offset;
10797 }
10798
10799
10800 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
10801    as described in 4.2.16.1
10802 */
10803 static int
10804 dissect_4_2_16_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10805     int offset, guint16 *bcp, gboolean *trunc)
10806 {
10807         /* create time */
10808         CHECK_BYTE_COUNT_SUBR(4);
10809         offset = dissect_smb_datetime(tvb, tree, offset,
10810                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
10811                 FALSE);
10812         *bcp -= 4;
10813
10814         /* access time */
10815         CHECK_BYTE_COUNT_SUBR(4);
10816         offset = dissect_smb_datetime(tvb, tree, offset,
10817                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
10818                 FALSE);
10819         *bcp -= 4;
10820
10821         /* last write time */
10822         CHECK_BYTE_COUNT_SUBR(4);
10823         offset = dissect_smb_datetime(tvb, tree, offset,
10824                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
10825                 FALSE);
10826         *bcp -= 4;
10827
10828         /* data size */
10829         CHECK_BYTE_COUNT_SUBR(4);
10830         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10831         COUNT_BYTES_SUBR(4);
10832
10833         /* allocation size */
10834         CHECK_BYTE_COUNT_SUBR(4);
10835         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10836         COUNT_BYTES_SUBR(4);
10837
10838         /* File Attributes */
10839         CHECK_BYTE_COUNT_SUBR(2);
10840         offset = dissect_file_attributes(tvb, tree, offset, 2);
10841         *bcp -= 2;
10842
10843         /* ea length */
10844         CHECK_BYTE_COUNT_SUBR(4);
10845         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10846         COUNT_BYTES_SUBR(4);
10847
10848         *trunc = FALSE;
10849         return offset;
10850 }
10851
10852 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
10853    as described in 4.2.16.2
10854 */
10855 static int
10856 dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10857     int offset, guint16 *bcp, gboolean *trunc)
10858 {
10859         guint8 name_len;
10860         guint16 data_len;
10861         /* EA size */
10862
10863         CHECK_BYTE_COUNT_SUBR(4);
10864         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10865         COUNT_BYTES_SUBR(4);
10866
10867         while (*bcp > 0) {
10868                 proto_item *item;
10869                 proto_tree *subtree;
10870                 int start_offset = offset;
10871                 guint8 *name;
10872
10873                 item = proto_tree_add_text(
10874                         tree, tvb, offset, 0, "Extended Attribute");
10875                 subtree = proto_item_add_subtree(item, ett_smb_ea);
10876
10877                 /* EA flags */
10878                 
10879                 CHECK_BYTE_COUNT_SUBR(1);
10880                 proto_tree_add_item(
10881                         subtree, hf_smb_ea_flags, tvb, offset, 1, TRUE);
10882                 COUNT_BYTES_SUBR(1);
10883
10884                 /* EA name length */
10885                 
10886                 name_len = tvb_get_guint8(tvb, offset);
10887
10888                 CHECK_BYTE_COUNT_SUBR(1);
10889                 proto_tree_add_item(
10890                         subtree, hf_smb_ea_name_length, tvb, offset, 1, TRUE);
10891                 COUNT_BYTES_SUBR(1);
10892
10893                 /* EA data length */
10894
10895                 data_len = tvb_get_letohs(tvb, offset);
10896                 
10897                 CHECK_BYTE_COUNT_SUBR(2);
10898                 proto_tree_add_item(
10899                         subtree, hf_smb_ea_data_length, tvb, offset, 2, TRUE);
10900                 COUNT_BYTES_SUBR(2);
10901
10902                 /* EA name */
10903
10904                 name = tvb_get_string(tvb, offset, name_len);
10905                 proto_item_append_text(item, ": %s", name);
10906                 g_free(name);
10907
10908                 CHECK_BYTE_COUNT_SUBR(name_len + 1);
10909                 proto_tree_add_item(
10910                         subtree, hf_smb_ea_name, tvb, offset, name_len + 1, 
10911                         TRUE);
10912                 COUNT_BYTES_SUBR(name_len + 1);
10913
10914                 /* EA data */
10915                 
10916                 CHECK_BYTE_COUNT_SUBR(data_len);
10917                 proto_tree_add_item(
10918                         subtree, hf_smb_ea_data, tvb, offset, data_len, TRUE);
10919                 COUNT_BYTES_SUBR(data_len);
10920
10921                 proto_item_set_len(item, offset - start_offset);
10922         }
10923
10924         *trunc = FALSE;
10925         return offset;
10926 }
10927
10928 /* this dissects the SMB_INFO_IS_NAME_VALID
10929    as described in 4.2.16.3
10930 */
10931 static int
10932 dissect_4_2_16_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10933     int offset, guint16 *bcp, gboolean *trunc)
10934 {
10935         smb_info_t *si = pinfo->private_data;
10936         int fn_len;
10937         const char *fn;
10938
10939         /* file name */
10940         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10941         CHECK_STRING_SUBR(fn);
10942         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10943                 fn);
10944         COUNT_BYTES_SUBR(fn_len);
10945
10946         *trunc = FALSE;
10947         return offset;
10948 }
10949
10950 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
10951    as described in 4.2.16.4
10952 */
10953 static int
10954 dissect_4_2_16_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10955     int offset, guint16 *bcp, gboolean *trunc)
10956 {
10957         /* create time */
10958         CHECK_BYTE_COUNT_SUBR(8);
10959         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
10960         *bcp -= 8;
10961
10962         /* access time */
10963         CHECK_BYTE_COUNT_SUBR(8);
10964         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
10965         *bcp -= 8;
10966
10967         /* last write time */
10968         CHECK_BYTE_COUNT_SUBR(8);
10969         offset = dissect_smb_64bit_time(tvb, tree, offset,
10970                 hf_smb_last_write_time);
10971         *bcp -= 8;
10972
10973         /* last change time */
10974         CHECK_BYTE_COUNT_SUBR(8);
10975         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
10976         *bcp -= 8;
10977
10978         /* File Attributes */
10979         CHECK_BYTE_COUNT_SUBR(4);
10980         offset = dissect_file_attributes(tvb, tree, offset, 4);
10981         *bcp -= 4;
10982
10983         *trunc = FALSE;
10984         return offset;
10985 }
10986
10987 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
10988    as described in 4.2.16.5
10989 */
10990 static int
10991 dissect_4_2_16_5(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10992     int offset, guint16 *bcp, gboolean *trunc)
10993 {
10994         /* allocation size */
10995         CHECK_BYTE_COUNT_SUBR(8);
10996         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10997         COUNT_BYTES_SUBR(8);
10998
10999         /* end of file */
11000         CHECK_BYTE_COUNT_SUBR(8);
11001         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11002         COUNT_BYTES_SUBR(8);
11003
11004         /* number of links */
11005         CHECK_BYTE_COUNT_SUBR(4);
11006         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
11007         COUNT_BYTES_SUBR(4);
11008
11009         /* delete pending */
11010         CHECK_BYTE_COUNT_SUBR(1);
11011         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
11012         COUNT_BYTES_SUBR(1);
11013
11014         /* is directory */
11015         CHECK_BYTE_COUNT_SUBR(1);
11016         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
11017         COUNT_BYTES_SUBR(1);
11018
11019         *trunc = FALSE;
11020         return offset;
11021 }
11022
11023 /* this dissects the SMB_QUERY_FILE_EA_INFO
11024    as described in 4.2.16.6
11025 */
11026 static int
11027 dissect_4_2_16_6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11028     int offset, guint16 *bcp, gboolean *trunc)
11029 {
11030         /* ea length */
11031         CHECK_BYTE_COUNT_SUBR(4);
11032         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11033         COUNT_BYTES_SUBR(4);
11034
11035         *trunc = FALSE;
11036         return offset;
11037 }
11038
11039 /* this dissects the SMB_QUERY_FILE_NAME_INFO
11040    as described in 4.2.16.7
11041    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
11042    as described in 4.2.16.9
11043 */
11044 static int
11045 dissect_4_2_16_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11046     int offset, guint16 *bcp, gboolean *trunc)
11047 {
11048         smb_info_t *si = pinfo->private_data;
11049         int fn_len;
11050         const char *fn;
11051
11052         /* file name len */
11053         CHECK_BYTE_COUNT_SUBR(4);
11054         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
11055         COUNT_BYTES_SUBR(4);
11056
11057         /* file name */
11058         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11059         CHECK_STRING_SUBR(fn);
11060         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11061                 fn);
11062         COUNT_BYTES_SUBR(fn_len);
11063
11064         *trunc = FALSE;
11065         return offset;
11066 }
11067
11068 /* this dissects the SMB_QUERY_FILE_ALL_INFO
11069    as described in 4.2.16.8
11070 */
11071 static int
11072 dissect_4_2_16_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11073     int offset, guint16 *bcp, gboolean *trunc)
11074 {
11075
11076         offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp, trunc);
11077         if (*trunc) {
11078                 return offset;
11079         }
11080         offset = dissect_4_2_16_5(tvb, pinfo, tree, offset, bcp, trunc);
11081         if (*trunc) {
11082                 return offset;
11083         }
11084
11085         /* index number */
11086         CHECK_BYTE_COUNT_SUBR(8);
11087         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
11088         COUNT_BYTES_SUBR(8);
11089
11090         offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp, trunc);
11091         if (*trunc)
11092                 return offset;
11093
11094         /* access flags */
11095         CHECK_BYTE_COUNT_SUBR(4);
11096         offset = dissect_smb_access_mask(tvb, tree, offset);
11097         COUNT_BYTES_SUBR(4);
11098
11099         /* index number */
11100         CHECK_BYTE_COUNT_SUBR(8);
11101         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
11102         COUNT_BYTES_SUBR(8);
11103
11104         /* current offset */
11105         CHECK_BYTE_COUNT_SUBR(8);
11106         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
11107         COUNT_BYTES_SUBR(8);
11108
11109         /* mode */
11110         CHECK_BYTE_COUNT_SUBR(4);
11111         offset = dissect_nt_create_options(tvb, tree, offset);
11112         *bcp -= 4;
11113
11114         /* alignment */
11115         CHECK_BYTE_COUNT_SUBR(4);
11116         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
11117         COUNT_BYTES_SUBR(4);
11118
11119         offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp, trunc);
11120
11121         return offset;
11122 }
11123
11124 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
11125    as described in 4.2.16.10
11126 */
11127 static int
11128 dissect_4_2_16_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11129     int offset, guint16 *bcp, gboolean *trunc)
11130 {
11131         proto_item *item;
11132         proto_tree *tree;
11133         int old_offset;
11134         guint32 neo;
11135         smb_info_t *si = pinfo->private_data;
11136         int fn_len;
11137         const char *fn;
11138         int padcnt;
11139
11140         for (;;) {
11141                 old_offset = offset;
11142
11143                 /* next entry offset */
11144                 CHECK_BYTE_COUNT_SUBR(4);
11145                 if(parent_tree){
11146                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
11147                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11148                 } else {
11149                         item = NULL;
11150                         tree = NULL;
11151                 }
11152
11153                 neo = tvb_get_letohl(tvb, offset);
11154                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11155                 COUNT_BYTES_SUBR(4);
11156
11157                 /* stream name len */
11158                 CHECK_BYTE_COUNT_SUBR(4);
11159                 fn_len = tvb_get_letohl(tvb, offset);
11160                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
11161                 COUNT_BYTES_SUBR(4);
11162
11163                 /* stream size */
11164                 CHECK_BYTE_COUNT_SUBR(8);
11165                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
11166                 COUNT_BYTES_SUBR(8);
11167
11168                 /* allocation size */
11169                 CHECK_BYTE_COUNT_SUBR(8);
11170                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11171                 COUNT_BYTES_SUBR(8);
11172
11173                 /* stream name */
11174                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11175                 CHECK_STRING_SUBR(fn);
11176                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
11177                         fn);
11178                 COUNT_BYTES_SUBR(fn_len);
11179
11180                 proto_item_append_text(item, ": %s", fn);
11181                 proto_item_set_len(item, offset-old_offset);
11182
11183                 if (neo == 0)
11184                         break;  /* no more structures */
11185
11186                 /* skip to next structure */
11187                 padcnt = (old_offset + neo) - offset;
11188                 if (padcnt < 0) {
11189                         /*
11190                          * XXX - this is bogus; flag it?
11191                          */
11192                         padcnt = 0;
11193                 }
11194                 if (padcnt != 0) {
11195                         CHECK_BYTE_COUNT_SUBR(padcnt);
11196                         COUNT_BYTES_SUBR(padcnt);
11197                 }
11198         }
11199
11200         *trunc = FALSE;
11201         return offset;
11202 }
11203
11204 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
11205    as described in 4.2.16.11
11206 */
11207 static int
11208 dissect_4_2_16_11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11209     int offset, guint16 *bcp, gboolean *trunc)
11210 {
11211         /* compressed file size */
11212         CHECK_BYTE_COUNT_SUBR(8);
11213         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
11214         COUNT_BYTES_SUBR(8);
11215
11216         /* compression format */
11217         CHECK_BYTE_COUNT_SUBR(2);
11218         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
11219         COUNT_BYTES_SUBR(2);
11220
11221         /* compression unit shift */
11222         CHECK_BYTE_COUNT_SUBR(1);
11223         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
11224         COUNT_BYTES_SUBR(1);
11225
11226         /* compression chunk shift */
11227         CHECK_BYTE_COUNT_SUBR(1);
11228         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
11229         COUNT_BYTES_SUBR(1);
11230
11231         /* compression cluster shift */
11232         CHECK_BYTE_COUNT_SUBR(1);
11233         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
11234         COUNT_BYTES_SUBR(1);
11235
11236         /* 3 reserved bytes */
11237         CHECK_BYTE_COUNT_SUBR(3);
11238         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
11239         COUNT_BYTES_SUBR(3);
11240
11241         *trunc = FALSE;
11242         return offset;
11243 }
11244
11245 /* 4.2.16.12 - SMB_QUERY_FILE_UNIX_BASIC */
11246
11247 static const value_string unix_file_type_vals[] = {
11248         { 0, "File" },
11249         { 1, "Directory" },
11250         { 2, "Symbolic link" },
11251         { 3, "Character device" },
11252         { 4, "Block device" },
11253         { 5, "FIFO" },
11254         { 6, "Socket" },
11255         { 0, NULL }
11256 };
11257
11258 static int
11259 dissect_4_2_16_12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11260                   int offset, guint16 *bcp, gboolean *trunc)
11261 {
11262         /* End of file (file size) */
11263         CHECK_BYTE_COUNT_SUBR(8);
11264         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
11265         COUNT_BYTES_SUBR(8);
11266
11267         /* Number of bytes */
11268         CHECK_BYTE_COUNT_SUBR(8);
11269         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
11270         COUNT_BYTES_SUBR(8);
11271
11272         /* Last status change */
11273         CHECK_BYTE_COUNT_SUBR(8);
11274         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
11275         *bcp -= 8;              /* dissect_smb_64bit_time() increments offset */
11276
11277         /* Last access time */
11278         CHECK_BYTE_COUNT_SUBR(8);
11279         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
11280         *bcp -= 8;
11281
11282         /* Last modification time */
11283         CHECK_BYTE_COUNT_SUBR(8);
11284         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
11285         *bcp -= 8;
11286
11287         /* File owner uid */
11288         CHECK_BYTE_COUNT_SUBR(8);
11289         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
11290         COUNT_BYTES_SUBR(8);
11291
11292         /* File group gid */
11293         CHECK_BYTE_COUNT_SUBR(8);
11294         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
11295         COUNT_BYTES_SUBR(8);
11296
11297         /* File type */
11298         CHECK_BYTE_COUNT_SUBR(4);
11299         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
11300         COUNT_BYTES_SUBR(4);
11301
11302         /* Major device number */
11303         CHECK_BYTE_COUNT_SUBR(8);
11304         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
11305         COUNT_BYTES_SUBR(8);
11306
11307         /* Minor device number */
11308         CHECK_BYTE_COUNT_SUBR(8);
11309         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
11310         COUNT_BYTES_SUBR(8);
11311
11312         /* Unique id */
11313         CHECK_BYTE_COUNT_SUBR(8);
11314         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
11315         COUNT_BYTES_SUBR(8);
11316
11317         /* Permissions */
11318         CHECK_BYTE_COUNT_SUBR(8);
11319         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
11320         COUNT_BYTES_SUBR(8);
11321
11322         /* Nlinks */
11323         CHECK_BYTE_COUNT_SUBR(8);
11324         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
11325         COUNT_BYTES_SUBR(8);
11326
11327         /* Sometimes there is one extra byte in the data field which I
11328            guess could be padding, but we are only using 4 or 8 byte
11329            data types so this is a bit confusing. -tpot */
11330
11331         *trunc = FALSE;
11332         return offset;
11333 }
11334
11335 /* 4.2.16.13 - SMB_QUERY_FILE_UNIX_LINK */
11336
11337 static int
11338 dissect_4_2_16_13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11339                   int offset, guint16 *bcp, gboolean *trunc)
11340 {
11341         smb_info_t *si = pinfo->private_data;
11342         const char *fn;
11343         int fn_len;
11344
11345         /* Link destination */
11346
11347         fn = get_unicode_or_ascii_string(
11348                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11349
11350         CHECK_STRING_SUBR(fn);
11351         proto_tree_add_string(
11352                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
11353         COUNT_BYTES_SUBR(fn_len);
11354
11355         *trunc = FALSE;
11356         return offset;
11357 }
11358
11359 /* this dissects the SMB_SET_FILE_DISPOSITION_INFO
11360    as described in 4.2.19.2
11361 */
11362 static int
11363 dissect_4_2_19_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11364     int offset, guint16 *bcp, gboolean *trunc)
11365 {
11366         /* marked for deletion? */
11367         CHECK_BYTE_COUNT_SUBR(1);
11368         proto_tree_add_item(tree, hf_smb_t2_marked_for_deletion, tvb, offset, 1, TRUE);
11369         COUNT_BYTES_SUBR(1);
11370
11371         *trunc = FALSE;
11372         return offset;
11373 }
11374
11375 /* this dissects the SMB_SET_FILE_ALLOCATION_INFO
11376    as described in 4.2.19.3
11377 */
11378 static int
11379 dissect_4_2_19_3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11380     int offset, guint16 *bcp, gboolean *trunc)
11381 {
11382         /* file allocation size */
11383         CHECK_BYTE_COUNT_SUBR(8);
11384         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11385         COUNT_BYTES_SUBR(8);
11386
11387         *trunc = FALSE;
11388         return offset;
11389 }
11390
11391 /* this dissects the SMB_SET_FILE_END_OF_FILE_INFO
11392    as described in 4.2.19.4
11393 */
11394 static int
11395 dissect_4_2_19_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11396     int offset, guint16 *bcp, gboolean *trunc)
11397 {
11398         /* file end of file offset */
11399         CHECK_BYTE_COUNT_SUBR(8);
11400         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11401         COUNT_BYTES_SUBR(8);
11402
11403         *trunc = FALSE;
11404         return offset;
11405 }
11406
11407 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION and
11408   TRANS2_QUERY_FILE_INFORMATION*/
11409 static int
11410 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11411     int offset, guint16 *bcp)
11412 {
11413         smb_info_t *si;
11414         gboolean trunc;
11415
11416         if(!*bcp){
11417                 return offset;
11418         }
11419
11420         si = (smb_info_t *)pinfo->private_data;
11421         switch(si->info_level){
11422         case 1:         /*Info Standard*/
11423                 
11424         case 2:         /*Info Query EA Size*/
11425                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
11426                     &trunc);
11427                 break;
11428         case 3:         /*Info Query EAs From List*/
11429         case 4:         /*Info Query All EAs*/
11430                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11431                     &trunc);
11432                 break;
11433         case 6:         /*Info Is Name Valid*/
11434                 offset = dissect_4_2_16_3(tvb, pinfo, tree, offset, bcp,
11435                     &trunc);
11436                 break;
11437         case 0x0101:    /*Query File Basic Info*/
11438         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
11439                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11440                     &trunc);
11441                 break;
11442         case 0x0102:    /*Query File Standard Info*/
11443         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
11444                 offset = dissect_4_2_16_5(tvb, pinfo, tree, offset, bcp,
11445                     &trunc);
11446                 break;
11447         case 0x0103:    /*Query File EA Info*/
11448         case 1007:      /* SMB_FILE_EA_INFORMATION */
11449                 offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp,
11450                     &trunc);
11451                 break;
11452         case 0x0104:    /*Query File Name Info*/
11453         case 1009:      /* SMB_FILE_NAME_INFORMATION */
11454                 offset = dissect_4_2_16_7(tvb, pinfo, tree, offset, bcp,
11455                     &trunc);
11456                 break;
11457         case 0x0107:    /*Query File All Info*/
11458         case 1018:      /* SMB_FILE_ALL_INFORMATION */
11459                 offset = dissect_4_2_16_8(tvb, pinfo, tree, offset, bcp,
11460                     &trunc);
11461                 break;
11462         case 0x0108:    /*Query File Alt File Info*/
11463         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
11464                 offset = dissect_4_2_16_7(tvb, pinfo, tree, offset, bcp,
11465                     &trunc);
11466                 break;
11467         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
11468                 ((smb_info_t *)(pinfo->private_data))->unicode = TRUE;
11469         case 0x0109:    /*Query File Stream Info*/
11470                 offset = dissect_4_2_16_10(tvb, pinfo, tree, offset, bcp,
11471                     &trunc);
11472                 break;
11473         case 0x010b:    /*Query File Compression Info*/
11474         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
11475                 offset = dissect_4_2_16_11(tvb, pinfo, tree, offset, bcp,
11476                     &trunc);
11477                 break;
11478         case 0x0200:    /* Query File Unix Basic*/
11479                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp, 
11480                                            &trunc);
11481                 break;
11482         case 0x0201:    /* Query File Unix Link*/
11483                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp, 
11484                                            &trunc);
11485                 break;
11486         case 0x0202:    /* Query File Unix HardLink*/
11487                 /* XXX add this from the SNIA doc */
11488                 break;
11489         }
11490
11491         return offset;
11492 }
11493
11494 /*dissect the data block for TRANS2_SET_PATH_INFORMATION and
11495   TRANS2_SET_FILE_INFORMATION*/
11496 static int
11497 dissect_spi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11498     int offset, guint16 *bcp)
11499 {
11500         smb_info_t *si;
11501         gboolean trunc;
11502
11503         if(!*bcp){
11504                 return offset;
11505         }
11506
11507         si = (smb_info_t *)pinfo->private_data;
11508         switch(si->info_level){
11509         case 1:         /*Info Standard*/
11510                 
11511         case 2:         /*Info Query EA Size*/
11512                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
11513                     &trunc);
11514                 break;
11515         case 4:         /*Info Query All EAs*/
11516                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11517                     &trunc);
11518                 break;
11519         case 0x0101:    /*Set File Basic Info*/
11520                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11521                     &trunc);
11522                 break;
11523         case 0x0102:    /*Set File Disposition Info*/
11524                 offset = dissect_4_2_19_2(tvb, pinfo, tree, offset, bcp,
11525                     &trunc);
11526                 break;
11527         case 0x0103:    /*Set File Allocation Info*/
11528                 offset = dissect_4_2_19_3(tvb, pinfo, tree, offset, bcp,
11529                     &trunc);
11530                 break;
11531         case 0x0104:    /*Set End Of File Info*/
11532                 offset = dissect_4_2_19_4(tvb, pinfo, tree, offset, bcp,
11533                     &trunc);
11534                 break;
11535         case 0x0200:    /*Set File Unix Basic.  Same as query. */
11536                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
11537                     &trunc);
11538                 break;
11539         case 0x0201:    /*Set File Unix Link.  Same as query. */
11540                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
11541                     &trunc);
11542                 break;
11543         case 0x0203:    /*Set File Unix HardLink.  Same as link query. */
11544                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
11545                     &trunc);
11546                 break;
11547         case 1004:
11548                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11549                     &trunc);
11550                 break;
11551         case 1010:
11552         case 1013:
11553         case 1014:
11554         case 1016:
11555         case 1019:
11556         case 1020:
11557         case 1023:
11558         case 1025:
11559         case 1029:
11560         case 1032:
11561         case 1039:
11562         case 1040:
11563                 /* XXX: TODO, extra levels discovered by tridge */
11564                 break;
11565         }
11566
11567         return offset;
11568 }
11569
11570
11571 static const true_false_string tfs_quota_flags_deny_disk = {
11572         "DENY DISK SPACE for users exceeding quota limit",
11573         "Do NOT deny disk space for users exceeding quota limit"
11574 };
11575 static const true_false_string tfs_quota_flags_log_limit = {
11576         "LOG EVENT when a user exceeds their QUOTA LIMIT",
11577         "Do NOT log event when a user exceeds their quota limit"
11578 };
11579 static const true_false_string tfs_quota_flags_log_warning = {
11580         "LOG EVENT when a user exceeds their WARNING LEVEL",
11581         "Do NOT log event when a user exceeds their warning level"
11582 };
11583 static const true_false_string tfs_quota_flags_enabled = {
11584         "Quotas are ENABLED of this fs",
11585         "Quotas are NOT enabled on this fs"
11586 };
11587 static void
11588 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11589 {
11590         guint8 mask;
11591         proto_item *item = NULL;
11592         proto_tree *tree = NULL;
11593
11594         mask = tvb_get_guint8(tvb, offset);
11595
11596         if(parent_tree){
11597                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
11598                         "Quota Flags: 0x%02x %s", mask,
11599                         mask?"Enabled":"Disabled");
11600                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
11601         }
11602
11603         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
11604                 tvb, offset, 1, mask);
11605         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
11606                 tvb, offset, 1, mask);
11607         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
11608                 tvb, offset, 1, mask);
11609
11610         if(mask && (!(mask&0x01))){
11611                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
11612                         tvb, offset, 1, 0x01);
11613         } else {
11614                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
11615                         tvb, offset, 1, mask);
11616         }
11617
11618 }
11619
11620 static int
11621 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
11622 {
11623         /* first 24 bytes are unknown */
11624         CHECK_BYTE_COUNT_TRANS_SUBR(24);
11625         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11626                     offset, 24, TRUE);
11627         COUNT_BYTES_TRANS_SUBR(24);
11628
11629         /* number of bytes for quota warning */
11630         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11631         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
11632         COUNT_BYTES_TRANS_SUBR(8);
11633
11634         /* number of bytes for quota limit */
11635         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11636         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
11637         COUNT_BYTES_TRANS_SUBR(8);
11638
11639         /* one byte of quota flags */
11640         CHECK_BYTE_COUNT_TRANS_SUBR(1);
11641         dissect_quota_flags(tvb, tree, offset);
11642         COUNT_BYTES_TRANS_SUBR(1);
11643
11644         /* these 7 bytes are unknown */
11645         CHECK_BYTE_COUNT_TRANS_SUBR(7);
11646         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11647                     offset, 7, TRUE);
11648         COUNT_BYTES_TRANS_SUBR(7);
11649
11650         return offset;
11651 }
11652
11653 static int
11654 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
11655     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
11656 {
11657         proto_item *item = NULL;
11658         proto_tree *tree = NULL;
11659         smb_info_t *si;
11660
11661         si = (smb_info_t *)pinfo->private_data;
11662
11663         if(parent_tree){
11664                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
11665                                 "%s Data",
11666                                 val_to_str(subcmd, trans2_cmd_vals,
11667                                                 "Unknown (0x%02x)"));
11668                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
11669         }
11670
11671         switch(subcmd){
11672         case 0x00:      /*TRANS2_OPEN2*/
11673                 /* XXX dont know how to decode FEAList */
11674                 break;
11675         case 0x01:      /*TRANS2_FIND_FIRST2*/
11676                 /* XXX dont know how to decode FEAList */
11677                 break;
11678         case 0x02:      /*TRANS2_FIND_NEXT2*/
11679                 /* XXX dont know how to decode FEAList */
11680                 break;
11681         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
11682                 /* no data field in this request */
11683                 break;
11684         case 0x04:      /* TRANS2_SET_QUOTA */
11685                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
11686                 break;
11687         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
11688                 /* no data field in this request */
11689                 /*
11690                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11691                  * Extensions Version 3.0, Document Version 1.11,
11692                  * July 19, 1990" says there may be "Additional
11693                  * FileInfoLevel dependent information" here.
11694                  *
11695                  * Was that just a cut-and-pasteo?
11696                  * TRANS2_SET_PATH_INFORMATION *does* have that information
11697                  * here.
11698                  */
11699                 break;
11700         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
11701                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
11702                 break;
11703         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
11704                 /* no data field in this request */
11705                 /*
11706                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11707                  * Extensions Version 3.0, Document Version 1.11,
11708                  * July 19, 1990" says there may be "Additional
11709                  * FileInfoLevel dependent information" here.
11710                  *
11711                  * Was that just a cut-and-pasteo?
11712                  * TRANS2_SET_FILE_INFORMATION *does* have that information
11713                  * here.
11714                  */
11715                 break;
11716         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
11717                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
11718                 break;
11719         case 0x09:      /*TRANS2_FSCTL*/
11720                 /*XXX dont know how to decode this yet */
11721
11722                 /*
11723                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11724                  * Extensions Version 3.0, Document Version 1.11,
11725                  * July 19, 1990" says this this contains a
11726                  * "File system specific data block".  (That means we
11727                  * may not be able to dissect it in any case.)
11728                  */
11729                 break;
11730         case 0x0a:      /*TRANS2_IOCTL2*/
11731                 /*XXX dont know how to decode this yet */
11732
11733                 /*
11734                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11735                  * Extensions Version 3.0, Document Version 1.11,
11736                  * July 19, 1990" says this this contains a
11737                  * "Device/function specific data block".  (That
11738                  * means we may not be able to dissect it in any case.)
11739                  */
11740                 break;
11741         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11742                 /*XXX dont know how to decode this yet */
11743
11744                 /*
11745                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11746                  * Extensions Version 3.0, Document Version 1.11,
11747                  * July 19, 1990" says this this contains "additional
11748                  * level dependent match data".
11749                  */
11750                 break;
11751         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11752                 /*XXX dont know how to decode this yet */
11753
11754                 /*
11755                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11756                  * Extensions Version 3.0, Document Version 1.11,
11757                  * July 19, 1990" says this this contains "additional
11758                  * level dependent monitor information".
11759                  */
11760                 break;
11761         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11762                 /* XXX optional FEAList, unknown what FEAList looks like*/
11763                 break;
11764         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11765                 /*XXX dont know how to decode this yet */
11766                 break;
11767         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11768                 /* no data field in this request */
11769                 break;
11770         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11771                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
11772                 break;
11773         }
11774
11775         /* ooops there were data we didnt know how to process */
11776         if(dc != 0){
11777                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
11778                 offset += dc;
11779         }
11780
11781         return offset;
11782 }
11783
11784
11785 static void
11786 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
11787     proto_tree *tree)
11788 {
11789         int i;
11790         int offset;
11791         guint length;
11792
11793         /*
11794          * Show the setup words.
11795          */
11796         if (s_tvb != NULL) {
11797                 length = tvb_reported_length(s_tvb);
11798                 for (i = 0, offset = 0; length >= 2;
11799                     i++, offset += 2, length -= 2) {
11800                         /*
11801                          * XXX - add a setup word filterable field?
11802                          */
11803                         proto_tree_add_text(tree, s_tvb, offset, 2,
11804                             "Setup Word %d: 0x%04x", i,
11805                             tvb_get_letohs(s_tvb, offset));
11806                 }
11807         }
11808
11809         /*
11810          * Show the parameters, if any.
11811          */
11812         if (p_tvb != NULL) {
11813                 length = tvb_reported_length(p_tvb);
11814                 if (length != 0) {
11815                         proto_tree_add_text(tree, p_tvb, 0, length,
11816                             "Parameters: %s",
11817                             tvb_bytes_to_str(p_tvb, 0, length));
11818                 }
11819         }
11820
11821         /*
11822          * Show the data, if any.
11823          */
11824         if (d_tvb != NULL) {
11825                 length = tvb_reported_length(d_tvb);
11826                 if (length != 0) {
11827                         proto_tree_add_text(tree, d_tvb, 0, length,
11828                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
11829                 }
11830         }
11831 }
11832
11833 /* This routine handles the following 4 calls
11834    Transaction  0x25
11835    Transaction Secondary 0x26
11836    Transaction2 0x32
11837    Transaction2 Secondary 0x33
11838 */
11839 static int
11840 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
11841 {
11842         guint8 wc, sc=0;
11843         int so=offset;
11844         int sl=0;
11845         int spo=offset;
11846         int spc=0;
11847         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
11848         int subcmd = -1;
11849         guint32 to;
11850         int an_len;
11851         const char *an = NULL;
11852         smb_info_t *si;
11853         smb_transact2_info_t *t2i;
11854         smb_transact_info_t *tri;
11855         guint16 bc;
11856         int padcnt;
11857         gboolean dissected_trans;
11858
11859         si = (smb_info_t *)pinfo->private_data;
11860
11861         WORD_COUNT;
11862
11863         if(wc==8){
11864                 /*secondary client request*/
11865
11866                 /* total param count, only a 16bit integer here*/
11867                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11868                 offset += 2;
11869
11870                 /* total data count , only 16bit integer here*/
11871                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11872                 offset += 2;
11873
11874                 /* param count */
11875                 pc = tvb_get_letohs(tvb, offset);
11876                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11877                 offset += 2;
11878
11879                 /* param offset */
11880                 po = tvb_get_letohs(tvb, offset);
11881                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11882                 offset += 2;
11883
11884                 /* param disp */
11885                 pd = tvb_get_letohs(tvb, offset);
11886                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
11887                 offset += 2;
11888
11889                 /* data count */
11890                 dc = tvb_get_letohs(tvb, offset);
11891                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11892                 offset += 2;
11893
11894                 /* data offset */
11895                 od = tvb_get_letohs(tvb, offset);
11896                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11897                 offset += 2;
11898
11899                 /* data disp */
11900                 dd = tvb_get_letohs(tvb, offset);
11901                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
11902                 offset += 2;
11903
11904                 if(si->cmd==SMB_COM_TRANSACTION2){
11905                         guint16 fid;
11906
11907                         /* fid */
11908                         fid = tvb_get_letohs(tvb, offset);
11909                         add_fid(tvb, pinfo, tree, offset, 2, fid);
11910
11911                         offset += 2;
11912                 }
11913
11914                 /* There are no setup words. */
11915                 so = offset;
11916                 sc = 0;
11917                 sl = 0;
11918         } else {
11919                 /* it is not a secondary request */
11920
11921                 /* total param count , only a 16 bit integer here*/
11922                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11923                 offset += 2;
11924
11925                 /* total data count , only 16bit integer here*/
11926                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11927                 offset += 2;
11928
11929                 /* max param count , only 16bit integer here*/
11930                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11931                 offset += 2;
11932
11933                 /* max data count, only 16bit integer here*/
11934                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11935                 offset += 2;
11936
11937                 /* max setup count, only 16bit integer here*/
11938                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
11939                 offset += 1;
11940
11941                 /* reserved byte */
11942                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11943                 offset += 1;
11944
11945                 /* transaction flags */
11946                 tf = dissect_transaction_flags(tvb, tree, offset);
11947                 offset += 2;
11948
11949                 /* timeout */
11950                 to = tvb_get_letohl(tvb, offset);
11951                 if (to == 0)
11952                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
11953                 else if (to == 0xffffffff)
11954                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
11955                 else
11956                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
11957                 offset += 4;
11958
11959                 /* 2 reserved bytes */
11960                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
11961                 offset += 2;
11962
11963                 /* param count */
11964                 pc = tvb_get_letohs(tvb, offset);
11965                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11966                 offset += 2;
11967
11968                 /* param offset */
11969                 po = tvb_get_letohs(tvb, offset);
11970                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11971                 offset += 2;
11972
11973                 /* param displacement is zero here */
11974                 pd = 0;
11975
11976                 /* data count */
11977                 dc = tvb_get_letohs(tvb, offset);
11978                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11979                 offset += 2;
11980
11981                 /* data offset */
11982                 od = tvb_get_letohs(tvb, offset);
11983                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11984                 offset += 2;
11985
11986                 /* data displacement is zero here */
11987                 dd = 0;
11988
11989                 /* setup count */
11990                 sc = tvb_get_guint8(tvb, offset);
11991                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
11992                 offset += 1;
11993
11994                 /* reserved byte */
11995                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11996                 offset += 1;
11997
11998                 /* this is where the setup bytes, if any start */
11999                 so = offset;
12000                 sl = sc*2;
12001
12002                 /* if there were any setup bytes, decode them */
12003                 if(sc){
12004                         switch(si->cmd){
12005
12006                         case SMB_COM_TRANSACTION2:
12007                                 /* TRANSACTION2 only has one setup word and
12008                                    that is the subcommand code.
12009
12010                                    XXX - except for TRANS2_FSCTL
12011                                    and TRANS2_IOCTL. */
12012                                 subcmd = tvb_get_letohs(tvb, offset);
12013                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
12014                                     tvb, offset, 2, subcmd);
12015                                 if (check_col(pinfo->cinfo, COL_INFO)) {
12016                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
12017                                             val_to_str(subcmd, trans2_cmd_vals,
12018                                                 "Unknown (0x%02x)"));
12019                                 }
12020                                 if (!si->unidir) {
12021                                         if(!pinfo->fd->flags.visited){
12022                                                 /*
12023                                                  * Allocate a new
12024                                                  * smb_transact2_info_t
12025                                                  * structure.
12026                                                  */
12027                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
12028                                                 t2i->subcmd = subcmd;
12029                                                 t2i->info_level = -1;
12030                                                 t2i->resume_keys = FALSE;
12031                                                 si->sip->extra_info = t2i;
12032                                         }
12033                                 }
12034
12035                                 /*
12036                                  * XXX - process TRANS2_FSCTL and
12037                                  * TRANS2_IOCTL setup words here.
12038                                  */
12039                                 break;
12040
12041                         case SMB_COM_TRANSACTION:
12042                                 /* TRANSACTION setup words processed below */
12043                                 break;
12044                         }
12045
12046                         offset += sl;
12047                 }
12048         }
12049
12050         BYTE_COUNT;
12051
12052         if(wc!=8){
12053                 /* primary request */
12054                 /* name is NULL if transaction2 */
12055                 if(si->cmd == SMB_COM_TRANSACTION){
12056                         /* Transaction Name */
12057                         an = get_unicode_or_ascii_string(tvb, &offset,
12058                                 si->unicode, &an_len, FALSE, FALSE, &bc);
12059                         if (an == NULL)
12060                                 goto endofcommand;
12061                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
12062                                 offset, an_len, an);
12063                         COUNT_BYTES(an_len);
12064                 }
12065         }
12066
12067         /*
12068          * The pipe or mailslot arguments for Transaction start with
12069          * the first setup word (or where the first setup word would
12070          * be if there were any setup words), and run to the current
12071          * offset (which could mean that there aren't any).
12072          */
12073         spo = so;
12074         spc = offset - spo;
12075
12076         /* parameters */
12077         if(po>offset){
12078                 /* We have some initial padding bytes.
12079                 */
12080                 padcnt = po-offset;
12081                 if (padcnt > bc)
12082                         padcnt = bc;
12083                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12084                 COUNT_BYTES(padcnt);
12085         }
12086         if(pc){
12087                 CHECK_BYTE_COUNT(pc);
12088                 switch(si->cmd) {
12089
12090                 case SMB_COM_TRANSACTION2:
12091                         /* TRANSACTION2 parameters*/
12092                         offset = dissect_transaction2_request_parameters(tvb,
12093                             pinfo, tree, offset, subcmd, pc);
12094                         bc -= pc;
12095                         break;
12096
12097                 case SMB_COM_TRANSACTION:
12098                         /* TRANSACTION parameters processed below */
12099                         COUNT_BYTES(pc);
12100                         break;
12101                 }
12102         }
12103
12104         /* data */
12105         if(od>offset){
12106                 /* We have some initial padding bytes.
12107                 */
12108                 padcnt = od-offset;
12109                 if (padcnt > bc)
12110                         padcnt = bc;
12111                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12112                 COUNT_BYTES(padcnt);
12113         }
12114         if(dc){
12115                 CHECK_BYTE_COUNT(dc);
12116                 switch(si->cmd){
12117
12118                 case SMB_COM_TRANSACTION2:
12119                         /* TRANSACTION2 data*/
12120                         offset = dissect_transaction2_request_data(tvb, pinfo,
12121                             tree, offset, subcmd, dc);
12122                         bc -= dc;
12123                         break;
12124
12125                 case SMB_COM_TRANSACTION:
12126                         /* TRANSACTION data processed below */
12127                         COUNT_BYTES(dc);
12128                         break;
12129                 }
12130         }
12131
12132         /*TRANSACTION request parameters */
12133         if(si->cmd==SMB_COM_TRANSACTION){
12134                 /*XXX replace this block with a function and use that one
12135                      for both requests/responses*/
12136                 if(dd==0){
12137                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
12138                         tvbuff_t *sp_tvb, *pd_tvb;
12139
12140                         if(pc>0){
12141                                 if(pc>tvb_length_remaining(tvb, po)){
12142                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
12143                                 } else {
12144                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
12145                                 }
12146                         } else {
12147                                 p_tvb = NULL;
12148                         }
12149                         if(dc>0){
12150                                 if(dc>tvb_length_remaining(tvb, od)){
12151                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
12152                                 } else {
12153                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
12154                                 }
12155                         } else {
12156                                 d_tvb = NULL;
12157                         }
12158                         if(sl){
12159                                 if(sl>tvb_length_remaining(tvb, so)){
12160                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
12161                                 } else {
12162                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
12163                                 }
12164                         } else {
12165                                 s_tvb = NULL;
12166                         }
12167
12168                         if (!si->unidir) {
12169                                 if(!pinfo->fd->flags.visited){
12170                                         /*
12171                                          * Allocate a new smb_transact_info_t
12172                                          * structure.
12173                                          */
12174                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
12175                                         tri->subcmd = -1;
12176                                         tri->trans_subcmd = -1;
12177                                         tri->function = -1;
12178                                         tri->fid = -1;
12179                                         tri->lanman_cmd = 0;
12180                                         tri->param_descrip = NULL;
12181                                         tri->data_descrip = NULL;
12182                                         tri->aux_data_descrip = NULL;
12183                                         tri->info_level = -1;
12184                                         si->sip->extra_info = tri;
12185                                 } else {
12186                                         /*
12187                                          * We already filled the structure
12188                                          * in; don't bother doing so again.
12189                                          */
12190                                         tri = NULL;
12191                                 }
12192                         } else {
12193                                 /*
12194                                  * This is a unidirectional message, for
12195                                  * which there will be no reply; don't
12196                                  * bother allocating an "smb_transact_info_t"
12197                                  * structure for it.
12198                                  */
12199                                 tri = NULL;
12200                         }
12201                         dissected_trans = FALSE;
12202                         if(strncmp("\\PIPE\\", an, 6) == 0){
12203                                 if (tri != NULL)
12204                                         tri->subcmd=TRANSACTION_PIPE;
12205
12206                                 /*
12207                                  * A tvbuff containing the setup words and
12208                                  * the pipe path.
12209                                  */
12210                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
12211
12212                                 /*
12213                                  * A tvbuff containing the parameters and the
12214                                  * data.
12215                                  */
12216                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
12217
12218                                 dissected_trans = dissect_pipe_smb(sp_tvb,
12219                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
12220                                     top_tree);
12221
12222                                 /* In case we did not see the TreeConnect call,
12223                                    store this TID here as well as a IPC TID 
12224                                    so we know that future Read/Writes to this 
12225                                    TID is (probably) DCERPC.
12226                                 */
12227                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
12228                                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
12229                                 }
12230                                 g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
12231                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
12232                                 if (tri != NULL)
12233                                         tri->subcmd=TRANSACTION_MAILSLOT;
12234
12235                                 /*
12236                                  * A tvbuff containing the setup words and
12237                                  * the mailslot path.
12238                                  */
12239                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
12240                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
12241                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
12242                         }
12243                         if (!dissected_trans)
12244                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
12245                 } else {
12246                         if(check_col(pinfo->cinfo, COL_INFO)){
12247                                 col_append_str(pinfo->cinfo, COL_INFO,
12248                                         "[transact continuation]");
12249                         }
12250                 }
12251         }
12252
12253         END_OF_SMB
12254
12255         return offset;
12256 }
12257
12258
12259
12260 static int
12261 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12262     int offset, guint16 *bcp, gboolean *trunc)
12263 {
12264         int fn_len;
12265         const char *fn;
12266         int old_offset = offset;
12267         proto_item *item = NULL;
12268         proto_tree *tree = NULL;
12269         smb_info_t *si;
12270         smb_transact2_info_t *t2i;
12271         gboolean resume_keys = FALSE;
12272
12273         si = (smb_info_t *)pinfo->private_data;
12274         if (si->sip != NULL) {
12275                 t2i = si->sip->extra_info;
12276                 if (t2i != NULL)
12277                         resume_keys = t2i->resume_keys;
12278         }
12279
12280         if(parent_tree){
12281                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12282                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12283                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12284         }
12285
12286         if (resume_keys) {
12287                 /* resume key */
12288                 CHECK_BYTE_COUNT_SUBR(4);
12289                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
12290                 COUNT_BYTES_SUBR(4);
12291         }
12292
12293         /* create time */
12294         CHECK_BYTE_COUNT_SUBR(4);
12295         offset = dissect_smb_datetime(tvb, tree, offset,
12296                 hf_smb_create_time,
12297                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
12298         *bcp -= 4;
12299
12300         /* access time */
12301         CHECK_BYTE_COUNT_SUBR(4);
12302         offset = dissect_smb_datetime(tvb, tree, offset,
12303                 hf_smb_access_time,
12304                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
12305         *bcp -= 4;
12306
12307         /* last write time */
12308         CHECK_BYTE_COUNT_SUBR(4);
12309         offset = dissect_smb_datetime(tvb, tree, offset,
12310                 hf_smb_last_write_time,
12311                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
12312         *bcp -= 4;
12313
12314         /* data size */
12315         CHECK_BYTE_COUNT_SUBR(4);
12316         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12317         COUNT_BYTES_SUBR(4);
12318
12319         /* allocation size */
12320         CHECK_BYTE_COUNT_SUBR(4);
12321         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
12322         COUNT_BYTES_SUBR(4);
12323
12324         /* File Attributes */
12325         CHECK_BYTE_COUNT_SUBR(2);
12326         offset = dissect_file_attributes(tvb, tree, offset, 2);
12327         *bcp -= 2;
12328
12329         /* file name len */
12330         CHECK_BYTE_COUNT_SUBR(1);
12331         fn_len = tvb_get_guint8(tvb, offset);
12332         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
12333         COUNT_BYTES_SUBR(1);
12334         if (si->unicode)
12335                 fn_len += 2;    /* include terminating '\0' */
12336         else
12337                 fn_len++;       /* include terminating '\0' */
12338
12339         /* file name */
12340         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12341         CHECK_STRING_SUBR(fn);
12342         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12343                 fn);
12344         COUNT_BYTES_SUBR(fn_len);
12345
12346         if (check_col(pinfo->cinfo, COL_INFO)) {
12347                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12348                 fn);
12349         }
12350
12351         proto_item_append_text(item, " File: %s", fn);
12352         proto_item_set_len(item, offset-old_offset);
12353
12354         *trunc = FALSE;
12355         return offset;
12356 }
12357
12358 static int
12359 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12360     int offset, guint16 *bcp, gboolean *trunc)
12361 {
12362         int fn_len;
12363         const char *fn;
12364         int old_offset = offset;
12365         proto_item *item = NULL;
12366         proto_tree *tree = NULL;
12367         smb_info_t *si;
12368         smb_transact2_info_t *t2i;
12369         gboolean resume_keys = FALSE;
12370
12371         si = (smb_info_t *)pinfo->private_data;
12372         if (si->sip != NULL) {
12373                 t2i = si->sip->extra_info;
12374                 if (t2i != NULL)
12375                         resume_keys = t2i->resume_keys;
12376         }
12377
12378         if(parent_tree){
12379                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12380                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12381                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12382         }
12383
12384         if (resume_keys) {
12385                 /* resume key */
12386                 CHECK_BYTE_COUNT_SUBR(4);
12387                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
12388                 COUNT_BYTES_SUBR(4);
12389         }
12390
12391         /* create time */
12392         CHECK_BYTE_COUNT_SUBR(4);
12393         offset = dissect_smb_datetime(tvb, tree, offset,
12394                 hf_smb_create_time,
12395                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
12396         *bcp -= 4;
12397
12398         /* access time */
12399         CHECK_BYTE_COUNT_SUBR(4);
12400         offset = dissect_smb_datetime(tvb, tree, offset,
12401                 hf_smb_access_time,
12402                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
12403         *bcp -= 4;
12404
12405         /* last write time */
12406         CHECK_BYTE_COUNT_SUBR(4);
12407         offset = dissect_smb_datetime(tvb, tree, offset,
12408                 hf_smb_last_write_time,
12409                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
12410         *bcp -= 4;
12411
12412         /* data size */
12413         CHECK_BYTE_COUNT_SUBR(4);
12414         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12415         COUNT_BYTES_SUBR(4);
12416
12417         /* allocation size */
12418         CHECK_BYTE_COUNT_SUBR(4);
12419         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
12420         COUNT_BYTES_SUBR(4);
12421
12422         /* File Attributes */
12423         CHECK_BYTE_COUNT_SUBR(2);
12424         offset = dissect_file_attributes(tvb, tree, offset, 2);
12425         *bcp -= 2;
12426
12427         /* ea length */
12428         CHECK_BYTE_COUNT_SUBR(4);
12429         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12430         COUNT_BYTES_SUBR(4);
12431
12432         /* file name len */
12433         CHECK_BYTE_COUNT_SUBR(1);
12434         fn_len = tvb_get_guint8(tvb, offset);
12435         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
12436         COUNT_BYTES_SUBR(1);
12437         if (si->unicode)
12438                 fn_len += 2;    /* include terminating '\0' */
12439         else
12440                 fn_len++;       /* include terminating '\0' */
12441
12442         /* file name */
12443         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12444         CHECK_STRING_SUBR(fn);
12445         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12446                 fn);
12447         COUNT_BYTES_SUBR(fn_len);
12448
12449         if (check_col(pinfo->cinfo, COL_INFO)) {
12450                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12451                 fn);
12452         }
12453
12454         proto_item_append_text(item, " File: %s", fn);
12455         proto_item_set_len(item, offset-old_offset);
12456
12457         *trunc = FALSE;
12458         return offset;
12459 }
12460
12461 static int
12462 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12463     int offset, guint16 *bcp, gboolean *trunc)
12464 {
12465         int fn_len;
12466         const char *fn;
12467         int old_offset = offset;
12468         proto_item *item = NULL;
12469         proto_tree *tree = NULL;
12470         smb_info_t *si;
12471         guint32 neo;
12472         int padcnt;
12473
12474         si = (smb_info_t *)pinfo->private_data;
12475
12476         if(parent_tree){
12477                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12478                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12479                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12480         }
12481
12482         /*
12483          * We assume that the presence of a next entry offset implies the
12484          * absence of a resume key, as appears to be the case for 4.3.4.6.
12485          */
12486
12487         /* next entry offset */
12488         CHECK_BYTE_COUNT_SUBR(4);
12489         neo = tvb_get_letohl(tvb, offset);
12490         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12491         COUNT_BYTES_SUBR(4);
12492
12493         /* file index */
12494         CHECK_BYTE_COUNT_SUBR(4);
12495         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12496         COUNT_BYTES_SUBR(4);
12497
12498         /* create time */
12499         CHECK_BYTE_COUNT_SUBR(8);
12500         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12501         *bcp -= 8;
12502
12503         /* access time */
12504         CHECK_BYTE_COUNT_SUBR(8);
12505         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12506         *bcp -= 8;
12507
12508         /* last write time */
12509         CHECK_BYTE_COUNT_SUBR(8);
12510         offset = dissect_smb_64bit_time(tvb, tree, offset,
12511                 hf_smb_last_write_time);
12512         *bcp -= 8;
12513
12514         /* last change time */
12515         CHECK_BYTE_COUNT_SUBR(8);
12516         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12517         *bcp -= 8;
12518
12519         /* end of file */
12520         CHECK_BYTE_COUNT_SUBR(8);
12521         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12522         COUNT_BYTES_SUBR(8);
12523
12524         /* allocation size */
12525         CHECK_BYTE_COUNT_SUBR(8);
12526         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12527         COUNT_BYTES_SUBR(8);
12528
12529         /* Extended File Attributes */
12530         CHECK_BYTE_COUNT_SUBR(4);
12531         offset = dissect_file_ext_attr(tvb, tree, offset);
12532         *bcp -= 4;
12533
12534         /* file name len */
12535         CHECK_BYTE_COUNT_SUBR(4);
12536         fn_len = tvb_get_letohl(tvb, offset);
12537         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12538         COUNT_BYTES_SUBR(4);
12539
12540         /* file name */
12541         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12542         CHECK_STRING_SUBR(fn);
12543         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12544                 fn);
12545         COUNT_BYTES_SUBR(fn_len);
12546
12547         if (check_col(pinfo->cinfo, COL_INFO)) {
12548                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12549                 fn);
12550         }
12551
12552         /* skip to next structure */
12553         if(neo){
12554                 padcnt = (old_offset + neo) - offset;
12555                 if (padcnt < 0) {
12556                         /*
12557                          * XXX - this is bogus; flag it?
12558                          */
12559                         padcnt = 0;
12560                 }
12561                 if (padcnt != 0) {
12562                         CHECK_BYTE_COUNT_SUBR(padcnt);
12563                         COUNT_BYTES_SUBR(padcnt);
12564                 }
12565         }
12566
12567         proto_item_append_text(item, " File: %s", fn);
12568         proto_item_set_len(item, offset-old_offset);
12569
12570         *trunc = FALSE;
12571         return offset;
12572 }
12573
12574 static int
12575 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12576     int offset, guint16 *bcp, gboolean *trunc)
12577 {
12578         int fn_len;
12579         const char *fn;
12580         int old_offset = offset;
12581         proto_item *item = NULL;
12582         proto_tree *tree = NULL;
12583         smb_info_t *si;
12584         guint32 neo;
12585         int padcnt;
12586
12587         si = (smb_info_t *)pinfo->private_data;
12588
12589         if(parent_tree){
12590                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12591                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12592                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12593         }
12594
12595         /*
12596          * We assume that the presence of a next entry offset implies the
12597          * absence of a resume key, as appears to be the case for 4.3.4.6.
12598          */
12599
12600         /* next entry offset */
12601         CHECK_BYTE_COUNT_SUBR(4);
12602         neo = tvb_get_letohl(tvb, offset);
12603         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12604         COUNT_BYTES_SUBR(4);
12605
12606         /* file index */
12607         CHECK_BYTE_COUNT_SUBR(4);
12608         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12609         COUNT_BYTES_SUBR(4);
12610
12611         /* create time */
12612         CHECK_BYTE_COUNT_SUBR(8);
12613         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12614         *bcp -= 8;
12615
12616         /* access time */
12617         CHECK_BYTE_COUNT_SUBR(8);
12618         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12619         *bcp -= 8;
12620
12621         /* last write time */
12622         CHECK_BYTE_COUNT_SUBR(8);
12623         offset = dissect_smb_64bit_time(tvb, tree, offset,
12624                 hf_smb_last_write_time);
12625         *bcp -= 8;
12626
12627         /* last change time */
12628         CHECK_BYTE_COUNT_SUBR(8);
12629         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12630         *bcp -= 8;
12631
12632         /* end of file */
12633         CHECK_BYTE_COUNT_SUBR(8);
12634         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12635         COUNT_BYTES_SUBR(8);
12636
12637         /* allocation size */
12638         CHECK_BYTE_COUNT_SUBR(8);
12639         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12640         COUNT_BYTES_SUBR(8);
12641
12642         /* Extended File Attributes */
12643         CHECK_BYTE_COUNT_SUBR(4);
12644         offset = dissect_file_ext_attr(tvb, tree, offset);
12645         *bcp -= 4;
12646
12647         /* file name len */
12648         CHECK_BYTE_COUNT_SUBR(4);
12649         fn_len = tvb_get_letohl(tvb, offset);
12650         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12651         COUNT_BYTES_SUBR(4);
12652
12653         /* ea length */
12654         CHECK_BYTE_COUNT_SUBR(4);
12655         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12656         COUNT_BYTES_SUBR(4);
12657
12658         /* file name */
12659         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12660         CHECK_STRING_SUBR(fn);
12661         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12662                 fn);
12663         COUNT_BYTES_SUBR(fn_len);
12664
12665         if (check_col(pinfo->cinfo, COL_INFO)) {
12666                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12667                 fn);
12668         }
12669
12670         /* skip to next structure */
12671         if(neo){
12672                 padcnt = (old_offset + neo) - offset;
12673                 if (padcnt < 0) {
12674                         /*
12675                          * XXX - this is bogus; flag it?
12676                          */
12677                         padcnt = 0;
12678                 }
12679                 if (padcnt != 0) {
12680                         CHECK_BYTE_COUNT_SUBR(padcnt);
12681                         COUNT_BYTES_SUBR(padcnt);
12682                 }
12683         }
12684
12685         proto_item_append_text(item, " File: %s", fn);
12686         proto_item_set_len(item, offset-old_offset);
12687
12688         *trunc = FALSE;
12689         return offset;
12690 }
12691
12692 static int
12693 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12694     int offset, guint16 *bcp, gboolean *trunc)
12695 {
12696         int fn_len, sfn_len;
12697         const char *fn, *sfn;
12698         int old_offset = offset;
12699         proto_item *item = NULL;
12700         proto_tree *tree = NULL;
12701         smb_info_t *si;
12702         guint32 neo;
12703         int padcnt;
12704
12705         si = (smb_info_t *)pinfo->private_data;
12706
12707         if(parent_tree){
12708                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12709                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12710                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12711         }
12712
12713         /*
12714          * XXX - I have not seen any of these that contain a resume
12715          * key, even though some of the requests had the "return resume
12716          * key" flag set.
12717          */
12718
12719         /* next entry offset */
12720         CHECK_BYTE_COUNT_SUBR(4);
12721         neo = tvb_get_letohl(tvb, offset);
12722         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12723         COUNT_BYTES_SUBR(4);
12724
12725         /* file index */
12726         CHECK_BYTE_COUNT_SUBR(4);
12727         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12728         COUNT_BYTES_SUBR(4);
12729
12730         /* create time */
12731         CHECK_BYTE_COUNT_SUBR(8);
12732         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12733         *bcp -= 8;
12734
12735         /* access time */
12736         CHECK_BYTE_COUNT_SUBR(8);
12737         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12738         *bcp -= 8;
12739
12740         /* last write time */
12741         CHECK_BYTE_COUNT_SUBR(8);
12742         offset = dissect_smb_64bit_time(tvb, tree, offset,
12743                 hf_smb_last_write_time);
12744         *bcp -= 8;
12745
12746         /* last change time */
12747         CHECK_BYTE_COUNT_SUBR(8);
12748         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12749         *bcp -= 8;
12750
12751         /* end of file */
12752         CHECK_BYTE_COUNT_SUBR(8);
12753         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12754         COUNT_BYTES_SUBR(8);
12755
12756         /* allocation size */
12757         CHECK_BYTE_COUNT_SUBR(8);
12758         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12759         COUNT_BYTES_SUBR(8);
12760
12761         /* Extended File Attributes */
12762         CHECK_BYTE_COUNT_SUBR(4);
12763         offset = dissect_file_ext_attr(tvb, tree, offset);
12764         *bcp -= 4;
12765
12766         /* file name len */
12767         CHECK_BYTE_COUNT_SUBR(4);
12768         fn_len = tvb_get_letohl(tvb, offset);
12769         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12770         COUNT_BYTES_SUBR(4);
12771
12772         /*
12773          * EA length.
12774          *
12775          * XXX - in one captures, this has the topmost bit set, and the
12776          * rest of the bits have the value 7.  Is the topmost bit being
12777          * set some indication that the value *isn't* the length of
12778          * the EAs?
12779          */
12780         CHECK_BYTE_COUNT_SUBR(4);
12781         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12782         COUNT_BYTES_SUBR(4);
12783
12784         /* short file name len */
12785         CHECK_BYTE_COUNT_SUBR(1);
12786         sfn_len = tvb_get_guint8(tvb, offset);
12787         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
12788         COUNT_BYTES_SUBR(1);
12789
12790         /* reserved byte */
12791         CHECK_BYTE_COUNT_SUBR(1);
12792         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12793         COUNT_BYTES_SUBR(1);
12794
12795         /* short file name */
12796         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
12797         CHECK_STRING_SUBR(sfn);
12798         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
12799                 sfn);
12800         COUNT_BYTES_SUBR(24);
12801
12802         /* file name */
12803         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12804         CHECK_STRING_SUBR(fn);
12805         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12806                 fn);
12807         COUNT_BYTES_SUBR(fn_len);
12808
12809         if (check_col(pinfo->cinfo, COL_INFO)) {
12810                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12811                 fn);
12812         }
12813
12814         /* skip to next structure */
12815         if(neo){
12816                 padcnt = (old_offset + neo) - offset;
12817                 if (padcnt < 0) {
12818                         /*
12819                          * XXX - this is bogus; flag it?
12820                          */
12821                         padcnt = 0;
12822                 }
12823                 if (padcnt != 0) {
12824                         CHECK_BYTE_COUNT_SUBR(padcnt);
12825                         COUNT_BYTES_SUBR(padcnt);
12826                 }
12827         }
12828
12829         proto_item_append_text(item, " File: %s", fn);
12830         proto_item_set_len(item, offset-old_offset);
12831
12832         *trunc = FALSE;
12833         return offset;
12834 }
12835
12836 static int
12837 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12838     int offset, guint16 *bcp, gboolean *trunc)
12839 {
12840         int fn_len;
12841         const char *fn;
12842         int old_offset = offset;
12843         proto_item *item = NULL;
12844         proto_tree *tree = NULL;
12845         smb_info_t *si;
12846         guint32 neo;
12847         int padcnt;
12848
12849         si = (smb_info_t *)pinfo->private_data;
12850
12851         if(parent_tree){
12852                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12853                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12854                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12855         }
12856
12857         /*
12858          * We assume that the presence of a next entry offset implies the
12859          * absence of a resume key, as appears to be the case for 4.3.4.6.
12860          */
12861
12862         /* next entry offset */
12863         CHECK_BYTE_COUNT_SUBR(4);
12864         neo = tvb_get_letohl(tvb, offset);
12865         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12866         COUNT_BYTES_SUBR(4);
12867
12868         /* file index */
12869         CHECK_BYTE_COUNT_SUBR(4);
12870         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12871         COUNT_BYTES_SUBR(4);
12872
12873         /* file name len */
12874         CHECK_BYTE_COUNT_SUBR(4);
12875         fn_len = tvb_get_letohl(tvb, offset);
12876         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12877         COUNT_BYTES_SUBR(4);
12878
12879         /* file name */
12880         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12881         CHECK_STRING_SUBR(fn);
12882         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12883                 fn);
12884         COUNT_BYTES_SUBR(fn_len);
12885
12886         if (check_col(pinfo->cinfo, COL_INFO)) {
12887                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12888                 fn);
12889         }
12890
12891         /* skip to next structure */
12892         if(neo){
12893                 padcnt = (old_offset + neo) - offset;
12894                 if (padcnt < 0) {
12895                         /*
12896                          * XXX - this is bogus; flag it?
12897                          */
12898                         padcnt = 0;
12899                 }
12900                 if (padcnt != 0) {
12901                         CHECK_BYTE_COUNT_SUBR(padcnt);
12902                         COUNT_BYTES_SUBR(padcnt);
12903                 }
12904         }
12905
12906         proto_item_append_text(item, " File: %s", fn);
12907         proto_item_set_len(item, offset-old_offset);
12908
12909         *trunc = FALSE;
12910         return offset;
12911 }
12912
12913 /* 4.3.4.8 - SMB_FIND_FILE_UNIX */
12914
12915 static int
12916 dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
12917                 proto_tree *tree, int offset, guint16 *bcp,
12918                 gboolean *trunc)
12919 {
12920         smb_info_t *si = pinfo->private_data;
12921         const char *fn;
12922         int fn_len;
12923
12924         /* NextEntryOffset */
12925         CHECK_BYTE_COUNT_SUBR(4);
12926         proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, TRUE);
12927         COUNT_BYTES_SUBR(4);
12928         
12929         /* ResumeKey */
12930         CHECK_BYTE_COUNT_SUBR(4);
12931         proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, TRUE);
12932         COUNT_BYTES_SUBR(4);
12933
12934         /* End of file (file size) */
12935         CHECK_BYTE_COUNT_SUBR(8);
12936         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
12937         COUNT_BYTES_SUBR(8);
12938
12939         /* Number of bytes */
12940         CHECK_BYTE_COUNT_SUBR(8);
12941         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
12942         COUNT_BYTES_SUBR(8);
12943
12944         /* Last status change */
12945         CHECK_BYTE_COUNT_SUBR(8);
12946         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
12947         *bcp -= 8;
12948
12949         /* Last access time */
12950         CHECK_BYTE_COUNT_SUBR(8);
12951         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
12952         *bcp -= 8;
12953
12954         /* Last modification time */
12955         CHECK_BYTE_COUNT_SUBR(8);
12956         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
12957         *bcp -= 8;
12958
12959         /* File owner uid */
12960         CHECK_BYTE_COUNT_SUBR(8);
12961         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
12962         COUNT_BYTES_SUBR(8);
12963
12964         /* File group gid */
12965         CHECK_BYTE_COUNT_SUBR(8);
12966         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
12967         COUNT_BYTES_SUBR(8);
12968
12969         /* File type */
12970         CHECK_BYTE_COUNT_SUBR(4);
12971         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
12972         COUNT_BYTES_SUBR(4);
12973
12974         /* Major device number */
12975         CHECK_BYTE_COUNT_SUBR(8);
12976         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
12977         COUNT_BYTES_SUBR(8);
12978
12979         /* Minor device number */
12980         CHECK_BYTE_COUNT_SUBR(8);
12981         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
12982         COUNT_BYTES_SUBR(8);
12983
12984         /* Unique id */
12985         CHECK_BYTE_COUNT_SUBR(8);
12986         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
12987         COUNT_BYTES_SUBR(8);
12988
12989         /* Permissions */
12990         CHECK_BYTE_COUNT_SUBR(8);
12991         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
12992         COUNT_BYTES_SUBR(8);
12993
12994         /* Nlinks */
12995         CHECK_BYTE_COUNT_SUBR(8);
12996         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
12997         COUNT_BYTES_SUBR(8);
12998
12999         /* Name */
13000
13001         fn = get_unicode_or_ascii_string(
13002                 tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
13003
13004         CHECK_STRING_SUBR(fn);
13005         proto_tree_add_string(
13006                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
13007         COUNT_BYTES_SUBR(fn_len);
13008
13009         /* Pad to 4 bytes */
13010
13011         if (offset % 4)
13012                 offset += 4 - (offset % 4);
13013
13014         *trunc = FALSE;
13015         return offset;
13016 }
13017
13018 /*dissect the data block for TRANS2_FIND_FIRST2*/
13019 static int
13020 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
13021     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
13022 {
13023         smb_info_t *si;
13024
13025         if(!*bcp){
13026                 return offset;
13027         }
13028
13029         si = (smb_info_t *)pinfo->private_data;
13030         switch(si->info_level){
13031         case 1:         /*Info Standard*/
13032                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
13033                     trunc);
13034                 break;
13035         case 2:         /*Info Query EA Size*/
13036                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13037                     trunc);
13038                 break;
13039         case 3:         /*Info Query EAs From List same as
13040                                 InfoQueryEASize*/
13041                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13042                     trunc);
13043                 break;
13044         case 0x0101:    /*Find File Directory Info*/
13045                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
13046                     trunc);
13047                 break;
13048         case 0x0102:    /*Find File Full Directory Info*/
13049                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
13050                     trunc);
13051                 break;
13052         case 0x0103:    /*Find File Names Info*/
13053                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
13054                     trunc);
13055                 break;
13056         case 0x0104:    /*Find File Both Directory Info*/
13057                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
13058                     trunc);
13059                 break;
13060         case 0x0202:    /*Find File UNIX*/
13061                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
13062                     trunc);
13063                 break;
13064         default:        /* unknown info level */
13065                 *trunc = FALSE;
13066                 break;
13067         }
13068         return offset;
13069 }
13070
13071
13072 static int
13073 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13074 {
13075         guint32 mask;
13076         proto_item *item = NULL;
13077         proto_tree *tree = NULL;
13078
13079         mask = tvb_get_letohl(tvb, offset);
13080
13081         if(parent_tree){
13082                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
13083                         "FS Attributes: 0x%08x", mask);
13084                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
13085         }
13086
13087         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
13088                 tvb, offset, 4, mask);
13089         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
13090                 tvb, offset, 4, mask);
13091         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
13092                 tvb, offset, 4, mask);
13093         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
13094                 tvb, offset, 4, mask);
13095         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
13096                 tvb, offset, 4, mask);
13097         proto_tree_add_boolean(tree, hf_smb_fs_attr_dim,
13098                 tvb, offset, 4, mask);
13099         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
13100                 tvb, offset, 4, mask);
13101
13102         offset += 4;
13103         return offset;
13104 }
13105
13106
13107 static int
13108 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13109 {
13110         guint32 mask;
13111         proto_item *item = NULL;
13112         proto_tree *tree = NULL;
13113
13114         mask = tvb_get_letohl(tvb, offset);
13115
13116         if(parent_tree){
13117                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
13118                         "Device Characteristics: 0x%08x", mask);
13119                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
13120         }
13121
13122         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
13123                 tvb, offset, 4, mask);
13124         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
13125                 tvb, offset, 4, mask);
13126         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
13127                 tvb, offset, 4, mask);
13128         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
13129                 tvb, offset, 4, mask);
13130         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
13131                 tvb, offset, 4, mask);
13132         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
13133                 tvb, offset, 4, mask);
13134         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
13135                 tvb, offset, 4, mask);
13136
13137         offset += 4;
13138         return offset;
13139 }
13140
13141 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
13142
13143 static const true_false_string tfs_smb_mac_access_ctrl = {
13144   "Macintosh Access Control Supported",
13145   "Macintosh Access Control Not Supported"
13146 };
13147
13148 static const true_false_string tfs_smb_mac_getset_comments = {
13149   "Macintosh Get & Set Comments Supported",
13150   "Macintosh Get & Set Comments Not Supported"
13151 };
13152
13153 static const true_false_string tfs_smb_mac_desktopdb_calls = {
13154   "Macintosh Get & Set Desktop Database Info Supported",
13155   "Macintosh Get & Set Desktop Database Info Supported"
13156 };
13157
13158 static const true_false_string tfs_smb_mac_unique_ids = {
13159   "Macintosh Unique IDs Supported",
13160   "Macintosh Unique IDs Not Supported"
13161 };
13162
13163 static const true_false_string tfs_smb_mac_streams = {
13164   "Macintosh and Streams Extensions Not Supported",
13165   "Macintosh and Streams Extensions Supported"
13166 };
13167
13168 static int
13169 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13170     int offset, guint16 *bcp)
13171 {
13172         smb_info_t *si;
13173         int fn_len, vll, fnl;
13174         const char *fn;
13175         guint support = 0;
13176         proto_item *item = NULL;
13177         proto_tree *ti = NULL;
13178
13179         if(!*bcp){
13180                 return offset;
13181         }
13182
13183         si = (smb_info_t *)pinfo->private_data;
13184         switch(si->info_level){
13185         case 1:         /* SMB_INFO_ALLOCATION */
13186                 /* filesystem id */
13187                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13188                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
13189                 COUNT_BYTES_TRANS_SUBR(4);
13190
13191                 /* sectors per unit */
13192                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13193                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13194                 COUNT_BYTES_TRANS_SUBR(4);
13195
13196                 /* units */
13197                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13198                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
13199                 COUNT_BYTES_TRANS_SUBR(4);
13200
13201                 /* avail units */
13202                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13203                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
13204                 COUNT_BYTES_TRANS_SUBR(4);
13205
13206                 /* bytes per sector, only 16bit integer here */
13207                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13208                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13209                 COUNT_BYTES_TRANS_SUBR(2);
13210
13211                 break;
13212         case 2:         /* SMB_INFO_VOLUME */
13213                 /* volume serial number */
13214                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13215                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
13216                 COUNT_BYTES_TRANS_SUBR(4);
13217
13218                 /* volume label length, only one byte here */
13219                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
13220                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
13221                 COUNT_BYTES_TRANS_SUBR(1);
13222
13223                 /* label */
13224                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
13225                 CHECK_STRING_TRANS_SUBR(fn);
13226                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13227                         fn);
13228                 COUNT_BYTES_TRANS_SUBR(fn_len);
13229
13230                 break;
13231         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
13232         case 1002:      /* SMB_FS_LABEL_INFORMATION */
13233                 /* volume label length */
13234                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13235                 vll = tvb_get_letohl(tvb, offset);
13236                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
13237                 COUNT_BYTES_TRANS_SUBR(4);
13238
13239                 /* label */
13240                 fn_len = vll;
13241                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13242                 CHECK_STRING_TRANS_SUBR(fn);
13243                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13244                         fn);
13245                 COUNT_BYTES_TRANS_SUBR(fn_len);
13246
13247                 break;
13248         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
13249         case 1001:      /* SMB_FS_VOLUME_INFORMATION */
13250                 /* create time */
13251                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13252                 offset = dissect_smb_64bit_time(tvb, tree, offset,
13253                         hf_smb_create_time);
13254                 *bcp -= 8;
13255
13256                 /* volume serial number */
13257                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13258                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
13259                 COUNT_BYTES_TRANS_SUBR(4);
13260
13261                 /* volume label length */
13262                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13263                 vll = tvb_get_letohl(tvb, offset);
13264                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
13265                 COUNT_BYTES_TRANS_SUBR(4);
13266
13267                 /* 2 reserved bytes */
13268                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13269                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
13270                 COUNT_BYTES_TRANS_SUBR(2);
13271
13272                 /* label */
13273                 fn_len = vll;
13274                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13275                 CHECK_STRING_TRANS_SUBR(fn);
13276                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13277                         fn);
13278                 COUNT_BYTES_TRANS_SUBR(fn_len);
13279
13280                 break;
13281         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
13282         case 1003:      /* SMB_FS_SIZE_INFORMATION */
13283                 /* allocation size */
13284                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13285                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13286                 COUNT_BYTES_TRANS_SUBR(8);
13287
13288                 /* free allocation units */
13289                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13290                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
13291                 COUNT_BYTES_TRANS_SUBR(8);
13292
13293                 /* sectors per unit */
13294                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13295                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13296                 COUNT_BYTES_TRANS_SUBR(4);
13297
13298                 /* bytes per sector */
13299                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13300                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
13301                 COUNT_BYTES_TRANS_SUBR(4);
13302
13303                 break;
13304         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
13305         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
13306                 /* device type */
13307                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13308                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
13309                 COUNT_BYTES_TRANS_SUBR(4);
13310
13311                 /* device characteristics */
13312                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13313                 offset = dissect_device_characteristics(tvb, tree, offset);
13314                 *bcp -= 4;
13315
13316                 break;
13317         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
13318         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
13319                 /* FS attributes */
13320                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13321                 offset = dissect_fs_attributes(tvb, tree, offset);
13322                 *bcp -= 4;
13323
13324                 /* max name len */
13325                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13326                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
13327                 COUNT_BYTES_TRANS_SUBR(4);
13328
13329                 /* fs name length */
13330                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13331                 fnl = tvb_get_letohl(tvb, offset);
13332                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
13333                 COUNT_BYTES_TRANS_SUBR(4);
13334
13335                 /* label */
13336                 fn_len = fnl;
13337                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13338                 CHECK_STRING_TRANS_SUBR(fn);
13339                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
13340                         fn);
13341                 COUNT_BYTES_TRANS_SUBR(fn_len);
13342
13343                 break;
13344         case 0x200: {   /* SMB_QUERY_CIFS_UNIX_INFO */
13345                 proto_item *item = NULL;
13346                 proto_tree *subtree = NULL;
13347                 guint32 caps_lo, caps_hi;
13348
13349                 /* MajorVersionNumber */
13350                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13351                 proto_tree_add_item(tree, hf_smb_unix_major_version, tvb, offset, 2, TRUE);
13352                 COUNT_BYTES_TRANS_SUBR(2);
13353
13354                 /* MinorVersionNumber */
13355                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13356                 proto_tree_add_item(tree, hf_smb_unix_minor_version, tvb, offset, 2, TRUE);
13357                 COUNT_BYTES_TRANS_SUBR(2);
13358
13359                 /* Capability */
13360
13361                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13362
13363                 caps_lo = tvb_get_letohl(tvb, offset);
13364                 caps_hi = tvb_get_letohl(tvb, offset + 4);
13365
13366                 if (tree) {
13367                         item = proto_tree_add_text(
13368                                 tree, tvb, offset, 8, "Capabilities: 0x%08x%08x", 
13369                                 caps_hi, caps_lo);
13370                         subtree = proto_item_add_subtree(
13371                                 item, ett_smb_unix_capabilities);
13372                 }
13373
13374                 proto_tree_add_boolean(
13375                         subtree, hf_smb_unix_capability_fcntl, tvb, offset, 8, 
13376                         caps_lo);
13377
13378                 proto_tree_add_boolean(
13379                         subtree, hf_smb_unix_capability_posix_acl, tvb, offset, 8, 
13380                         caps_lo);
13381
13382                 COUNT_BYTES_TRANS_SUBR(8);
13383
13384                 break;
13385         }
13386         case 0x301:     /* MAC_QUERY_FS_INFO */
13387                 /* Create time */
13388                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13389                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
13390                 *bcp -= 8;
13391                 /* Modify Time */
13392                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13393                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_modify_time);
13394                 *bcp -= 8;
13395                 /* Backup Time */
13396                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13397                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_backup_time);
13398                 *bcp -= 8;
13399                 /* Allocation blocks */
13400                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13401                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
13402                                     offset,
13403                                     4, TRUE);
13404                 COUNT_BYTES_TRANS_SUBR(4);
13405                 /* Allocation Block Size */
13406                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13407                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
13408                                     offset, 4, TRUE);
13409                 COUNT_BYTES_TRANS_SUBR(4);
13410                 /* Free Block Count */
13411                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13412                 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
13413                                     offset, 4, TRUE);
13414                 COUNT_BYTES_TRANS_SUBR(4);
13415                 /* Finder Info ... */
13416                 CHECK_BYTE_COUNT_TRANS_SUBR(32);
13417                 proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb,
13418                                             offset, 32,
13419                                             tvb_get_ptr(tvb, offset,32),
13420                                             "Finder Info: %s",
13421                                             tvb_format_text(tvb, offset, 32));
13422                 COUNT_BYTES_TRANS_SUBR(32);
13423                 /* Number Files */
13424                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13425                 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
13426                                     offset, 4, TRUE);
13427                 COUNT_BYTES_TRANS_SUBR(4);
13428                 /* Number of Root Directories */
13429                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13430                 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
13431                                     offset, 4, TRUE);
13432                 COUNT_BYTES_TRANS_SUBR(4);
13433                 /* Number of files */
13434                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13435                 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
13436                                     offset, 4, TRUE);
13437                 COUNT_BYTES_TRANS_SUBR(4);
13438                 /* Dir Count */
13439                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13440                 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
13441                                     offset, 4, TRUE);
13442                 COUNT_BYTES_TRANS_SUBR(4);
13443                 /* Mac Support Flags */
13444                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13445                 support = tvb_get_ntohl(tvb, offset);
13446                 item = proto_tree_add_text(tree, tvb, offset, 4,
13447                                            "Mac Support Flags: 0x%08x", support);
13448                 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
13449                 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
13450                                        tvb, offset, 4, support);
13451                 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
13452                                        tvb, offset, 4, support);
13453                 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
13454                                        tvb, offset, 4, support);
13455                 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
13456                                        tvb, offset, 4, support);
13457                 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
13458                                        tvb, offset, 4, support);
13459                 COUNT_BYTES_TRANS_SUBR(4);
13460                 break;
13461         case 1006:      /* QUERY_FS_QUOTA_INFO */
13462                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
13463                 break;
13464         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
13465                 /* allocation size */
13466                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13467                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13468                 COUNT_BYTES_TRANS_SUBR(8);
13469
13470                 /* caller free allocation units */
13471                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13472                 proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
13473                 COUNT_BYTES_TRANS_SUBR(8);
13474
13475                 /* actual free allocation units */
13476                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13477                 proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
13478                 COUNT_BYTES_TRANS_SUBR(8);
13479
13480                 /* sectors per unit */
13481                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13482                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13483                 COUNT_BYTES_TRANS_SUBR(4);
13484
13485                 /* bytes per sector */
13486                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13487                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
13488                 COUNT_BYTES_TRANS_SUBR(4);
13489                 break;
13490         case 1008: /* Query Object ID is GUID plus unknown data */ {
13491                 e_uuid_t fs_id;
13492                 char uuid_str[DCERPC_UUID_STR_LEN]; 
13493                 int uuid_str_len;
13494                 char drep = 0x10;
13495                 
13496                 CHECK_BYTE_COUNT_TRANS_SUBR(16);
13497
13498                 dcerpc_tvb_get_uuid (tvb, offset, &drep, &fs_id);
13499
13500                 uuid_str_len = snprintf(
13501                         uuid_str, DCERPC_UUID_STR_LEN, 
13502                         "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
13503                         fs_id.Data1, fs_id.Data2, fs_id.Data3,
13504                         fs_id.Data4[0], fs_id.Data4[1],
13505                         fs_id.Data4[2], fs_id.Data4[3],
13506                         fs_id.Data4[4], fs_id.Data4[5],
13507                         fs_id.Data4[6], fs_id.Data4[7]);
13508
13509                 proto_tree_add_string_format(
13510                         tree, hf_smb_fs_guid, tvb,
13511                         offset, 16, uuid_str, "GUID: %s", uuid_str);
13512
13513                 COUNT_BYTES_TRANS_SUBR(16);
13514                 break;
13515             }
13516         }
13517
13518         return offset;
13519 }
13520
13521 static int
13522 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
13523     proto_tree *parent_tree)
13524 {
13525         proto_item *item = NULL;
13526         proto_tree *tree = NULL;
13527         smb_info_t *si;
13528         smb_transact2_info_t *t2i;
13529         int count;
13530         gboolean trunc;
13531         int offset = 0;
13532         guint16 dc;
13533
13534         dc = tvb_reported_length(tvb);
13535
13536         si = (smb_info_t *)pinfo->private_data;
13537         if (si->sip != NULL)
13538                 t2i = si->sip->extra_info;
13539         else
13540                 t2i = NULL;
13541
13542         if(parent_tree){
13543                 if (t2i != NULL && t2i->subcmd != -1) {
13544                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13545                                 "%s Data",
13546                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
13547                                         "Unknown (0x%02x)"));
13548                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
13549                 } else {
13550                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13551                                 "Unknown Transaction2 Data");
13552                 }
13553         }
13554
13555         if (t2i == NULL) {
13556                 offset += dc;
13557                 return offset;
13558         }
13559         switch(t2i->subcmd){
13560         case 0x00:      /*TRANS2_OPEN2*/
13561                 /* XXX not implemented yet. See SNIA doc */
13562                 break;
13563         case 0x01:      /*TRANS2_FIND_FIRST2*/
13564                 /* returned data */
13565                 count = si->info_count;
13566
13567                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
13568                         col_append_fstr(pinfo->cinfo, COL_INFO,
13569                         ", Files:");
13570                 }
13571
13572                 while(count--){
13573                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
13574                                 offset, &dc, &trunc);
13575                         if (trunc)
13576                                 break;
13577                 }
13578                 break;
13579         case 0x02:      /*TRANS2_FIND_NEXT2*/
13580                 /* returned data */
13581                 count = si->info_count;
13582
13583                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
13584                         col_append_fstr(pinfo->cinfo, COL_INFO,
13585                         ", Files:");
13586                 }
13587
13588                 while(count--){
13589                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
13590                                 offset, &dc, &trunc);
13591                         if (trunc)
13592                                 break;
13593                 }
13594                 break;
13595         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
13596                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
13597                 break;
13598         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
13599                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
13600                 break;
13601         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
13602                 /* no data in this response */
13603                 break;
13604         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
13605                 /* identical to QUERY_PATH_INFO */
13606                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
13607                 break;
13608         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
13609                 /* no data in this response */
13610                 break;
13611         case 0x09:      /*TRANS2_FSCTL*/
13612                 /* XXX dont know how to dissect this one (yet)*/
13613
13614                 /*
13615                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13616                  * Extensions Version 3.0, Document Version 1.11,
13617                  * July 19, 1990" says this this contains a
13618                  * "File system specific return data block".
13619                  * (That means we may not be able to dissect it in any
13620                  * case.)
13621                  */
13622                 break;
13623         case 0x0a:      /*TRANS2_IOCTL2*/
13624                 /* XXX dont know how to dissect this one (yet)*/
13625
13626                 /*
13627                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13628                  * Extensions Version 3.0, Document Version 1.11,
13629                  * July 19, 1990" says this this contains a
13630                  * "Device/function specific return data block".
13631                  * (That means we may not be able to dissect it in any
13632                  * case.)
13633                  */
13634                 break;
13635         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
13636                 /* XXX dont know how to dissect this one (yet)*/
13637
13638                 /*
13639                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13640                  * Extensions Version 3.0, Document Version 1.11,
13641                  * July 19, 1990" says this this contains "the level
13642                  * dependent information about the changes which
13643                  * occurred".
13644                  */
13645                 break;
13646         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
13647                 /* XXX dont know how to dissect this one (yet)*/
13648
13649                 /*
13650                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13651                  * Extensions Version 3.0, Document Version 1.11,
13652                  * July 19, 1990" says this this contains "the level
13653                  * dependent information about the changes which
13654                  * occurred".
13655                  */
13656                 break;
13657         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
13658                 /* no data in this response */
13659                 break;
13660         case 0x0e:      /*TRANS2_SESSION_SETUP*/
13661                 /* XXX dont know how to dissect this one (yet)*/
13662                 break;
13663         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
13664                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
13665                 break;
13666         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13667                 /* the SNIA spec appears to say the response has no data */
13668                 break;
13669         case -1:
13670                 /*
13671                  * We don't know what the matching request was; don't
13672                  * bother putting anything else into the tree for the data.
13673                  */
13674                 offset += dc;
13675                 dc = 0;
13676                 break;
13677         }
13678
13679         /* ooops there were data we didnt know how to process */
13680         if(dc != 0){
13681                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
13682                 offset += dc;
13683         }
13684
13685         return offset;
13686 }
13687
13688
13689 static void
13690 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
13691 {
13692         proto_item *item = NULL;
13693         proto_tree *tree = NULL;
13694         smb_info_t *si;
13695         smb_transact2_info_t *t2i;
13696         guint16 fid;
13697         int lno;
13698         int offset = 0;
13699         int pc;
13700
13701         pc = tvb_reported_length(tvb);
13702
13703         si = (smb_info_t *)pinfo->private_data;
13704         if (si->sip != NULL)
13705                 t2i = si->sip->extra_info;
13706         else
13707                 t2i = NULL;
13708
13709         if(parent_tree){
13710                 if (t2i != NULL && t2i->subcmd != -1) {
13711                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13712                                 "%s Parameters",
13713                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
13714                                                 "Unknown (0x%02x)"));
13715                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
13716                 } else {
13717                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13718                                 "Unknown Transaction2 Parameters");
13719                 }
13720         }
13721
13722         if (t2i == NULL) {
13723                 offset += pc;
13724                 return;
13725         }
13726         switch(t2i->subcmd){
13727         case 0x00:      /*TRANS2_OPEN2*/
13728                 /* fid */
13729                 fid = tvb_get_letohs(tvb, offset);
13730                 add_fid(tvb, pinfo, tree, offset, 2, fid);
13731                 offset += 2;
13732
13733                 /*
13734                  * XXX - Microsoft Networks SMB File Sharing Protocol
13735                  * Extensions Version 3.0, Document Version 1.11,
13736                  * July 19, 1990 says that the file attributes, create
13737                  * time (which it says is the last modification time),
13738                  * data size, granted access, file type, and IPC state
13739                  * are returned only if bit 0 is set in the open flags,
13740                  * and that the EA length is returned only if bit 3
13741                  * is set in the open flags.  Does that mean that,
13742                  * at least in that SMB dialect, those fields are not
13743                  * present in the reply parameters if the bits in
13744                  * question aren't set?
13745                  */
13746
13747                 /* File Attributes */
13748                 offset = dissect_file_attributes(tvb, tree, offset, 2);
13749
13750                 /* create time */
13751                 offset = dissect_smb_datetime(tvb, tree, offset,
13752                         hf_smb_create_time,
13753                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
13754
13755                 /* data size */
13756                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
13757                 offset += 4;
13758
13759                 /* granted access */
13760                 offset = dissect_access(tvb, tree, offset, "Granted");
13761
13762                 /* File Type */
13763                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
13764                 offset += 2;
13765
13766                 /* IPC State */
13767                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
13768
13769                 /* open_action */
13770                 offset = dissect_open_action(tvb, tree, offset);
13771
13772                 /* server unique file ID */
13773                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
13774                 offset += 4;
13775
13776                 /* ea error offset, only a 16 bit integer here */
13777                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13778                 offset += 2;
13779
13780                 /* ea length */
13781                 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13782                 offset += 4;
13783
13784                 break;
13785         case 0x01:      /*TRANS2_FIND_FIRST2*/
13786                 /* Find First2 information level */
13787                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
13788
13789                 /* sid */
13790                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
13791                 offset += 2;
13792
13793                 /* search count */
13794                 si->info_count = tvb_get_letohs(tvb, offset);
13795                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13796                 offset += 2;
13797
13798                 /* end of search */
13799                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13800                 offset += 2;
13801
13802                 /* ea error offset, only a 16 bit integer here */
13803                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13804                 offset += 2;
13805
13806                 /* last name offset */
13807                 lno = tvb_get_letohs(tvb, offset);
13808                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13809                 offset += 2;
13810
13811                 break;
13812         case 0x02:      /*TRANS2_FIND_NEXT2*/
13813                 /* search count */
13814                 si->info_count = tvb_get_letohs(tvb, offset);
13815                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13816                 offset += 2;
13817
13818                 /* end of search */
13819                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13820                 offset += 2;
13821
13822                 /* ea_error_offset, only a 16 bit integer here*/
13823                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13824                 offset += 2;
13825
13826                 /* last name offset */
13827                 lno = tvb_get_letohs(tvb, offset);
13828                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13829                 offset += 2;
13830
13831                 break;
13832         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
13833                 /* no parameter block here */
13834                 break;
13835         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
13836                 /* ea_error_offset, only a 16 bit integer here*/
13837                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13838                 offset += 2;
13839
13840                 break;
13841         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
13842                 /* ea_error_offset, only a 16 bit integer here*/
13843                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13844                 offset += 2;
13845
13846                 break;
13847         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
13848                 /* ea_error_offset, only a 16 bit integer here*/
13849                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13850                 offset += 2;
13851
13852                 break;
13853         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
13854                 /* ea_error_offset, only a 16 bit integer here*/
13855                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13856                 offset += 2;
13857
13858                 break;
13859         case 0x09:      /*TRANS2_FSCTL*/
13860                 /* XXX dont know how to dissect this one (yet)*/
13861
13862                 /*
13863                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13864                  * Extensions Version 3.0, Document Version 1.11,
13865                  * July 19, 1990" says this this contains a
13866                  * "File system specific return parameter block".
13867                  * (That means we may not be able to dissect it in any
13868                  * case.)
13869                  */
13870                 break;
13871         case 0x0a:      /*TRANS2_IOCTL2*/
13872                 /* XXX dont know how to dissect this one (yet)*/
13873
13874                 /*
13875                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13876                  * Extensions Version 3.0, Document Version 1.11,
13877                  * July 19, 1990" says this this contains a
13878                  * "Device/function specific return parameter block".
13879                  * (That means we may not be able to dissect it in any
13880                  * case.)
13881                  */
13882                 break;
13883         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
13884                 /* Find Notify information level */
13885                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13886
13887                 /* Monitor handle */
13888                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
13889                 offset += 2;
13890
13891                 /* Change count */
13892                 si->info_count = tvb_get_letohs(tvb, offset);
13893                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13894                 offset += 2;
13895
13896                 /* ea_error_offset, only a 16 bit integer here*/
13897                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13898                 offset += 2;
13899
13900                 break;
13901         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
13902                 /* Find Notify information level */
13903                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13904
13905                 /* Change count */
13906                 si->info_count = tvb_get_letohs(tvb, offset);
13907                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13908                 offset += 2;
13909
13910                 /* ea_error_offset, only a 16 bit integer here*/
13911                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13912                 offset += 2;
13913
13914                 break;
13915         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
13916                 /* ea error offset, only a 16 bit integer here */
13917                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13918                 offset += 2;
13919
13920                 break;
13921         case 0x0e:      /*TRANS2_SESSION_SETUP*/
13922                 /* XXX dont know how to dissect this one (yet)*/
13923                 break;
13924         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
13925                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
13926                 break;
13927         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13928                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
13929                 break;
13930         case -1:
13931                 /*
13932                  * We don't know what the matching request was; don't
13933                  * bother putting anything else into the tree for the data.
13934                  */
13935                 offset += pc;
13936                 break;
13937         }
13938
13939         /* ooops there were data we didnt know how to process */
13940         if(offset<pc){
13941                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
13942                 offset += pc-offset;
13943         }
13944 }
13945
13946
13947 static int
13948 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13949 {
13950         guint8 sc, wc;
13951         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
13952         smb_info_t *si;
13953         smb_transact2_info_t *t2i = NULL;
13954         guint16 bc;
13955         int padcnt;
13956         gboolean dissected_trans;
13957         fragment_data *r_fd = NULL;
13958         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
13959         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
13960         gboolean save_fragmented;
13961
13962         si = (smb_info_t *)pinfo->private_data;
13963
13964         switch(si->cmd){
13965         case SMB_COM_TRANSACTION2:
13966                 /* transaction2 */
13967                 if (si->sip != NULL) {
13968                         t2i = si->sip->extra_info;
13969                 } else
13970                         t2i = NULL;
13971                 if (t2i == NULL) {
13972                         /*
13973                          * We didn't see the matching request, so we don't
13974                          * know what type of transaction this is.
13975                          */
13976                         proto_tree_add_text(tree, tvb, 0, 0,
13977                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
13978                         if (check_col(pinfo->cinfo, COL_INFO)) {
13979                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
13980                         }
13981                 } else {
13982                         si->info_level = t2i->info_level;
13983                         if (t2i->subcmd == -1) {
13984                                 /*
13985                                  * We didn't manage to extract the subcommand
13986                                  * from the matching request (perhaps because
13987                                  * the frame was short), so we don't know what
13988                                  * type of transaction this is.
13989                                  */
13990                                 proto_tree_add_text(tree, tvb, 0, 0,
13991                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
13992                                 if (check_col(pinfo->cinfo, COL_INFO)) {
13993                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
13994                                 }
13995                         } else {
13996                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
13997                                 if (check_col(pinfo->cinfo, COL_INFO)) {
13998                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
13999                                                 val_to_str(t2i->subcmd,
14000                                                         trans2_cmd_vals,
14001                                                         "<unknown (0x%02x)>"));
14002                                 }
14003                         }
14004                 }
14005                 break;
14006         }
14007
14008         WORD_COUNT;
14009
14010         /* total param count, only a 16bit integer here */
14011         tp = tvb_get_letohs(tvb, offset);
14012         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
14013         offset += 2;
14014
14015         /* total data count, only a 16 bit integer here */
14016         td = tvb_get_letohs(tvb, offset);
14017         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
14018         offset += 2;
14019
14020         /* 2 reserved bytes */
14021         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
14022         offset += 2;
14023
14024         /* param count */
14025         pc = tvb_get_letohs(tvb, offset);
14026         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
14027         offset += 2;
14028
14029         /* param offset */
14030         po = tvb_get_letohs(tvb, offset);
14031         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
14032         offset += 2;
14033
14034         /* param disp */
14035         pd = tvb_get_letohs(tvb, offset);
14036         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
14037         offset += 2;
14038
14039         /* data count */
14040         dc = tvb_get_letohs(tvb, offset);
14041         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
14042         offset += 2;
14043
14044         /* data offset */
14045         od = tvb_get_letohs(tvb, offset);
14046         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
14047         offset += 2;
14048
14049         /* data disp */
14050         dd = tvb_get_letohs(tvb, offset);
14051         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
14052         offset += 2;
14053
14054         /* setup count */
14055         sc = tvb_get_guint8(tvb, offset);
14056         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
14057         offset += 1;
14058
14059         /* reserved byte */
14060         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
14061         offset += 1;
14062
14063
14064         /* if there were any setup bytes, put them in a tvb for later */
14065         if(sc){
14066                 if((2*sc)>tvb_length_remaining(tvb, offset)){
14067                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
14068                 } else {
14069                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
14070                 }
14071                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
14072         } else {
14073                 s_tvb = NULL;
14074                 sp_tvb=NULL;
14075         }
14076         offset += 2*sc;
14077
14078
14079         BYTE_COUNT;
14080
14081
14082         /* reassembly of SMB Transaction data payload.
14083            In this section we do reassembly of both the data and parameters
14084            blocks of the SMB transaction command.
14085         */
14086         save_fragmented = pinfo->fragmented;
14087         /* do we need reassembly? */
14088         if( (td!=dc) || (tp!=pc) ){
14089                 /* oh yeah, either data or parameter section needs
14090                    reassembly
14091                 */
14092                 pinfo->fragmented = TRUE;
14093                 if(smb_trans_reassembly){
14094                         /* ...and we were told to do reassembly */
14095                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
14096                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
14097                                                              po, pc, pd, td+tp);
14098
14099                         }
14100                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
14101                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
14102                                                              od, dc, dd+tp, td+tp);
14103                         }
14104                 }
14105         }
14106
14107         /* if we got a reassembled fd structure from the reassembly routine we must
14108            create pd_tvb from it
14109         */
14110         if(r_fd){
14111                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
14112                                              r_fd->datalen);
14113                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
14114                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
14115                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
14116         }
14117
14118
14119         if(pd_tvb){
14120                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
14121                 if(tp){
14122                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
14123                 }
14124                 if(td){
14125                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
14126                 }
14127         } else {
14128                 /* It was not reassembled. Do as best as we can.
14129                  * in this case we always try to dissect the stuff if
14130                  * data and param displacement is 0. i.e. for the first
14131                  * (and maybe only) packet.
14132                  */
14133                 if( (pd==0) && (dd==0) ){
14134                         int min;
14135                         int reported_min;
14136                         min = MIN(pc,tvb_length_remaining(tvb,po));
14137                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
14138                         if(min && reported_min) {
14139                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
14140                         }
14141                         min = MIN(dc,tvb_length_remaining(tvb,od));
14142                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
14143                         if(min && reported_min) {
14144                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
14145                         }
14146                         /*
14147                          * A tvbuff containing the parameters
14148                          * and the data.
14149                          * XXX - check pc and dc as well?
14150                          */
14151                         if (tvb_length_remaining(tvb, po)){
14152                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
14153                         }
14154                 }
14155         }
14156
14157
14158
14159         /* parameters */
14160         if(po>offset){
14161                 /* We have some padding bytes.
14162                 */
14163                 padcnt = po-offset;
14164                 if (padcnt > bc)
14165                         padcnt = bc;
14166                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
14167                 COUNT_BYTES(padcnt);
14168         }
14169         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
14170                 /* TRANSACTION2 parameters*/
14171                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
14172         }
14173         COUNT_BYTES(pc);
14174
14175
14176         /* data */
14177         if(od>offset){
14178                 /* We have some initial padding bytes.
14179                 */
14180                 padcnt = od-offset;
14181                 if (padcnt > bc)
14182                         padcnt = bc;
14183                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
14184                 COUNT_BYTES(padcnt);
14185         }
14186         /*
14187          * If the data count is bigger than the count of bytes
14188          * remaining, clamp it so that the count of bytes remaining
14189          * doesn't go negative.
14190          */
14191         if (dc > bc)
14192                 dc = bc;
14193         COUNT_BYTES(dc);
14194
14195
14196
14197         /* from now on, everything is in separate tvbuffs so we dont count
14198            the bytes with COUNT_BYTES any more.
14199            neither do we reference offset any more (which by now points to the
14200            first byte AFTER this PDU */
14201
14202
14203         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
14204                 /* TRANSACTION2 parameters*/
14205                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
14206         }
14207
14208
14209         if(si->cmd==SMB_COM_TRANSACTION){
14210                 smb_transact_info_t *tri;
14211
14212                 dissected_trans = FALSE;
14213                 if (si->sip != NULL)
14214                         tri = si->sip->extra_info;
14215                 else
14216                         tri = NULL;
14217                 if (tri != NULL) {
14218                         switch(tri->subcmd){
14219
14220                         case TRANSACTION_PIPE:
14221                                 /* This function is safe to call for
14222                                    s_tvb==sp_tvb==NULL, i.e. if we don't
14223                                    know them at this point.
14224                                    It's also safe to call if "p_tvb"
14225                                    or "d_tvb" are null.
14226                                 */
14227                                 if( pd_tvb) {
14228                                         dissected_trans = dissect_pipe_smb(
14229                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
14230                                                 d_tvb, NULL, pinfo, top_tree);
14231                                 }
14232                                 break;
14233
14234                         case TRANSACTION_MAILSLOT:
14235                                 /* This one should be safe to call
14236                                    even if s_tvb and sp_tvb is NULL
14237                                 */
14238                                 if(d_tvb){
14239                                         dissected_trans = dissect_mailslot_smb(
14240                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
14241                                                 top_tree);
14242                                 }
14243                                 break;
14244                         }
14245                 }
14246                 if (!dissected_trans) {
14247                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
14248                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
14249                 }
14250         }
14251
14252
14253         if( (p_tvb==0) && (d_tvb==0) ){
14254                 if(check_col(pinfo->cinfo, COL_INFO)){
14255                         col_append_str(pinfo->cinfo, COL_INFO,
14256                                        "[transact continuation]");
14257                 }
14258         }
14259
14260         pinfo->fragmented = save_fragmented;
14261         END_OF_SMB
14262
14263         return offset;
14264 }
14265
14266
14267 static int
14268 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14269 {
14270         guint8 wc;
14271         guint16 bc;
14272
14273         WORD_COUNT;
14274
14275         /* Monitor handle */
14276         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
14277         offset += 2;
14278
14279         BYTE_COUNT;
14280
14281         END_OF_SMB
14282
14283         return offset;
14284 }
14285
14286 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14287    END Transaction/Transaction2 Primary and secondary requests
14288    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
14289
14290
14291 static int
14292 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14293 {
14294         guint8 wc;
14295         guint16 bc;
14296
14297         WORD_COUNT;
14298
14299         if (wc != 0) {
14300                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
14301                 offset += wc*2;
14302         }
14303
14304         BYTE_COUNT;
14305
14306         if (bc != 0) {
14307                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
14308                 offset += bc;
14309                 bc = 0;
14310         }
14311
14312         END_OF_SMB
14313
14314         return offset;
14315 }
14316
14317 typedef struct _smb_function {
14318        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14319        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14320 } smb_function;
14321
14322 static smb_function smb_dissector[256] = {
14323   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
14324   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
14325   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
14326   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
14327   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
14328   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
14329   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
14330   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
14331   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
14332   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
14333   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
14334   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
14335   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
14336   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
14337   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
14338   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
14339
14340   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
14341   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
14342   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
14343   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
14344   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
14345   /* 0x15 */  {dissect_unknown, dissect_unknown},
14346   /* 0x16 */  {dissect_unknown, dissect_unknown},
14347   /* 0x17 */  {dissect_unknown, dissect_unknown},
14348   /* 0x18 */  {dissect_unknown, dissect_unknown},
14349   /* 0x19 */  {dissect_unknown, dissect_unknown},
14350   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
14351   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
14352   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
14353   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
14354   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
14355   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
14356
14357   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
14358   /* 0x21 */  {dissect_unknown, dissect_unknown},
14359   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
14360   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
14361   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
14362   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
14363   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
14364   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
14365   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
14366   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
14367   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
14368   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
14369   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
14370   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
14371   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
14372   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
14373
14374   /* 0x30 */  {dissect_unknown, dissect_unknown},
14375   /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
14376   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
14377   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
14378   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
14379   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
14380   /* 0x36 */  {dissect_unknown, dissect_unknown},
14381   /* 0x37 */  {dissect_unknown, dissect_unknown},
14382   /* 0x38 */  {dissect_unknown, dissect_unknown},
14383   /* 0x39 */  {dissect_unknown, dissect_unknown},
14384   /* 0x3a */  {dissect_unknown, dissect_unknown},
14385   /* 0x3b */  {dissect_unknown, dissect_unknown},
14386   /* 0x3c */  {dissect_unknown, dissect_unknown},
14387   /* 0x3d */  {dissect_unknown, dissect_unknown},
14388   /* 0x3e */  {dissect_unknown, dissect_unknown},
14389   /* 0x3f */  {dissect_unknown, dissect_unknown},
14390
14391   /* 0x40 */  {dissect_unknown, dissect_unknown},
14392   /* 0x41 */  {dissect_unknown, dissect_unknown},
14393   /* 0x42 */  {dissect_unknown, dissect_unknown},
14394   /* 0x43 */  {dissect_unknown, dissect_unknown},
14395   /* 0x44 */  {dissect_unknown, dissect_unknown},
14396   /* 0x45 */  {dissect_unknown, dissect_unknown},
14397   /* 0x46 */  {dissect_unknown, dissect_unknown},
14398   /* 0x47 */  {dissect_unknown, dissect_unknown},
14399   /* 0x48 */  {dissect_unknown, dissect_unknown},
14400   /* 0x49 */  {dissect_unknown, dissect_unknown},
14401   /* 0x4a */  {dissect_unknown, dissect_unknown},
14402   /* 0x4b */  {dissect_unknown, dissect_unknown},
14403   /* 0x4c */  {dissect_unknown, dissect_unknown},
14404   /* 0x4d */  {dissect_unknown, dissect_unknown},
14405   /* 0x4e */  {dissect_unknown, dissect_unknown},
14406   /* 0x4f */  {dissect_unknown, dissect_unknown},
14407
14408   /* 0x50 */  {dissect_unknown, dissect_unknown},
14409   /* 0x51 */  {dissect_unknown, dissect_unknown},
14410   /* 0x52 */  {dissect_unknown, dissect_unknown},
14411   /* 0x53 */  {dissect_unknown, dissect_unknown},
14412   /* 0x54 */  {dissect_unknown, dissect_unknown},
14413   /* 0x55 */  {dissect_unknown, dissect_unknown},
14414   /* 0x56 */  {dissect_unknown, dissect_unknown},
14415   /* 0x57 */  {dissect_unknown, dissect_unknown},
14416   /* 0x58 */  {dissect_unknown, dissect_unknown},
14417   /* 0x59 */  {dissect_unknown, dissect_unknown},
14418   /* 0x5a */  {dissect_unknown, dissect_unknown},
14419   /* 0x5b */  {dissect_unknown, dissect_unknown},
14420   /* 0x5c */  {dissect_unknown, dissect_unknown},
14421   /* 0x5d */  {dissect_unknown, dissect_unknown},
14422   /* 0x5e */  {dissect_unknown, dissect_unknown},
14423   /* 0x5f */  {dissect_unknown, dissect_unknown},
14424
14425   /* 0x60 */  {dissect_unknown, dissect_unknown},
14426   /* 0x61 */  {dissect_unknown, dissect_unknown},
14427   /* 0x62 */  {dissect_unknown, dissect_unknown},
14428   /* 0x63 */  {dissect_unknown, dissect_unknown},
14429   /* 0x64 */  {dissect_unknown, dissect_unknown},
14430   /* 0x65 */  {dissect_unknown, dissect_unknown},
14431   /* 0x66 */  {dissect_unknown, dissect_unknown},
14432   /* 0x67 */  {dissect_unknown, dissect_unknown},
14433   /* 0x68 */  {dissect_unknown, dissect_unknown},
14434   /* 0x69 */  {dissect_unknown, dissect_unknown},
14435   /* 0x6a */  {dissect_unknown, dissect_unknown},
14436   /* 0x6b */  {dissect_unknown, dissect_unknown},
14437   /* 0x6c */  {dissect_unknown, dissect_unknown},
14438   /* 0x6d */  {dissect_unknown, dissect_unknown},
14439   /* 0x6e */  {dissect_unknown, dissect_unknown},
14440   /* 0x6f */  {dissect_unknown, dissect_unknown},
14441
14442   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
14443   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
14444   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
14445   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
14446   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
14447   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
14448   /* 0x76 */  {dissect_unknown, dissect_unknown},
14449   /* 0x77 */  {dissect_unknown, dissect_unknown},
14450   /* 0x78 */  {dissect_unknown, dissect_unknown},
14451   /* 0x79 */  {dissect_unknown, dissect_unknown},
14452   /* 0x7a */  {dissect_unknown, dissect_unknown},
14453   /* 0x7b */  {dissect_unknown, dissect_unknown},
14454   /* 0x7c */  {dissect_unknown, dissect_unknown},
14455   /* 0x7d */  {dissect_unknown, dissect_unknown},
14456   /* 0x7e */  {dissect_unknown, dissect_unknown},
14457   /* 0x7f */  {dissect_unknown, dissect_unknown},
14458
14459   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
14460   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
14461   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
14462   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
14463   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
14464   /* 0x85 */  {dissect_unknown, dissect_unknown},
14465   /* 0x86 */  {dissect_unknown, dissect_unknown},
14466   /* 0x87 */  {dissect_unknown, dissect_unknown},
14467   /* 0x88 */  {dissect_unknown, dissect_unknown},
14468   /* 0x89 */  {dissect_unknown, dissect_unknown},
14469   /* 0x8a */  {dissect_unknown, dissect_unknown},
14470   /* 0x8b */  {dissect_unknown, dissect_unknown},
14471   /* 0x8c */  {dissect_unknown, dissect_unknown},
14472   /* 0x8d */  {dissect_unknown, dissect_unknown},
14473   /* 0x8e */  {dissect_unknown, dissect_unknown},
14474   /* 0x8f */  {dissect_unknown, dissect_unknown},
14475
14476   /* 0x90 */  {dissect_unknown, dissect_unknown},
14477   /* 0x91 */  {dissect_unknown, dissect_unknown},
14478   /* 0x92 */  {dissect_unknown, dissect_unknown},
14479   /* 0x93 */  {dissect_unknown, dissect_unknown},
14480   /* 0x94 */  {dissect_unknown, dissect_unknown},
14481   /* 0x95 */  {dissect_unknown, dissect_unknown},
14482   /* 0x96 */  {dissect_unknown, dissect_unknown},
14483   /* 0x97 */  {dissect_unknown, dissect_unknown},
14484   /* 0x98 */  {dissect_unknown, dissect_unknown},
14485   /* 0x99 */  {dissect_unknown, dissect_unknown},
14486   /* 0x9a */  {dissect_unknown, dissect_unknown},
14487   /* 0x9b */  {dissect_unknown, dissect_unknown},
14488   /* 0x9c */  {dissect_unknown, dissect_unknown},
14489   /* 0x9d */  {dissect_unknown, dissect_unknown},
14490   /* 0x9e */  {dissect_unknown, dissect_unknown},
14491   /* 0x9f */  {dissect_unknown, dissect_unknown},
14492
14493   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
14494   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
14495   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
14496   /* 0xa3 */  {dissect_unknown, dissect_unknown},
14497   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
14498   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
14499   /* 0xa6 */  {dissect_unknown, dissect_unknown},
14500   /* 0xa7 */  {dissect_unknown, dissect_unknown},
14501   /* 0xa8 */  {dissect_unknown, dissect_unknown},
14502   /* 0xa9 */  {dissect_unknown, dissect_unknown},
14503   /* 0xaa */  {dissect_unknown, dissect_unknown},
14504   /* 0xab */  {dissect_unknown, dissect_unknown},
14505   /* 0xac */  {dissect_unknown, dissect_unknown},
14506   /* 0xad */  {dissect_unknown, dissect_unknown},
14507   /* 0xae */  {dissect_unknown, dissect_unknown},
14508   /* 0xaf */  {dissect_unknown, dissect_unknown},
14509
14510   /* 0xb0 */  {dissect_unknown, dissect_unknown},
14511   /* 0xb1 */  {dissect_unknown, dissect_unknown},
14512   /* 0xb2 */  {dissect_unknown, dissect_unknown},
14513   /* 0xb3 */  {dissect_unknown, dissect_unknown},
14514   /* 0xb4 */  {dissect_unknown, dissect_unknown},
14515   /* 0xb5 */  {dissect_unknown, dissect_unknown},
14516   /* 0xb6 */  {dissect_unknown, dissect_unknown},
14517   /* 0xb7 */  {dissect_unknown, dissect_unknown},
14518   /* 0xb8 */  {dissect_unknown, dissect_unknown},
14519   /* 0xb9 */  {dissect_unknown, dissect_unknown},
14520   /* 0xba */  {dissect_unknown, dissect_unknown},
14521   /* 0xbb */  {dissect_unknown, dissect_unknown},
14522   /* 0xbc */  {dissect_unknown, dissect_unknown},
14523   /* 0xbd */  {dissect_unknown, dissect_unknown},
14524   /* 0xbe */  {dissect_unknown, dissect_unknown},
14525   /* 0xbf */  {dissect_unknown, dissect_unknown},
14526
14527   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
14528   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
14529   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
14530   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
14531   /* 0xc4 */  {dissect_unknown, dissect_unknown},
14532   /* 0xc5 */  {dissect_unknown, dissect_unknown},
14533   /* 0xc6 */  {dissect_unknown, dissect_unknown},
14534   /* 0xc7 */  {dissect_unknown, dissect_unknown},
14535   /* 0xc8 */  {dissect_unknown, dissect_unknown},
14536   /* 0xc9 */  {dissect_unknown, dissect_unknown},
14537   /* 0xca */  {dissect_unknown, dissect_unknown},
14538   /* 0xcb */  {dissect_unknown, dissect_unknown},
14539   /* 0xcc */  {dissect_unknown, dissect_unknown},
14540   /* 0xcd */  {dissect_unknown, dissect_unknown},
14541   /* 0xce */  {dissect_unknown, dissect_unknown},
14542   /* 0xcf */  {dissect_unknown, dissect_unknown},
14543
14544   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
14545   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
14546   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
14547   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
14548   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
14549   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
14550   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
14551   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
14552   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
14553   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
14554   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
14555   /* 0xdb */  {dissect_unknown, dissect_unknown},
14556   /* 0xdc */  {dissect_unknown, dissect_unknown},
14557   /* 0xdd */  {dissect_unknown, dissect_unknown},
14558   /* 0xde */  {dissect_unknown, dissect_unknown},
14559   /* 0xdf */  {dissect_unknown, dissect_unknown},
14560
14561   /* 0xe0 */  {dissect_unknown, dissect_unknown},
14562   /* 0xe1 */  {dissect_unknown, dissect_unknown},
14563   /* 0xe2 */  {dissect_unknown, dissect_unknown},
14564   /* 0xe3 */  {dissect_unknown, dissect_unknown},
14565   /* 0xe4 */  {dissect_unknown, dissect_unknown},
14566   /* 0xe5 */  {dissect_unknown, dissect_unknown},
14567   /* 0xe6 */  {dissect_unknown, dissect_unknown},
14568   /* 0xe7 */  {dissect_unknown, dissect_unknown},
14569   /* 0xe8 */  {dissect_unknown, dissect_unknown},
14570   /* 0xe9 */  {dissect_unknown, dissect_unknown},
14571   /* 0xea */  {dissect_unknown, dissect_unknown},
14572   /* 0xeb */  {dissect_unknown, dissect_unknown},
14573   /* 0xec */  {dissect_unknown, dissect_unknown},
14574   /* 0xed */  {dissect_unknown, dissect_unknown},
14575   /* 0xee */  {dissect_unknown, dissect_unknown},
14576   /* 0xef */  {dissect_unknown, dissect_unknown},
14577
14578   /* 0xf0 */  {dissect_unknown, dissect_unknown},
14579   /* 0xf1 */  {dissect_unknown, dissect_unknown},
14580   /* 0xf2 */  {dissect_unknown, dissect_unknown},
14581   /* 0xf3 */  {dissect_unknown, dissect_unknown},
14582   /* 0xf4 */  {dissect_unknown, dissect_unknown},
14583   /* 0xf5 */  {dissect_unknown, dissect_unknown},
14584   /* 0xf6 */  {dissect_unknown, dissect_unknown},
14585   /* 0xf7 */  {dissect_unknown, dissect_unknown},
14586   /* 0xf8 */  {dissect_unknown, dissect_unknown},
14587   /* 0xf9 */  {dissect_unknown, dissect_unknown},
14588   /* 0xfa */  {dissect_unknown, dissect_unknown},
14589   /* 0xfb */  {dissect_unknown, dissect_unknown},
14590   /* 0xfc */  {dissect_unknown, dissect_unknown},
14591   /* 0xfd */  {dissect_unknown, dissect_unknown},
14592   /* 0xfe */  {dissect_unknown, dissect_unknown},
14593   /* 0xff */  {dissect_unknown, dissect_unknown},
14594 };
14595
14596 static int
14597 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
14598 {
14599         smb_info_t *si;
14600
14601         si = pinfo->private_data;
14602         if(cmd!=0xff){
14603                 proto_item *cmd_item;
14604                 proto_tree *cmd_tree;
14605                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14606
14607                 if (check_col(pinfo->cinfo, COL_INFO)) {
14608                         if(first_pdu){
14609                                 col_append_fstr(pinfo->cinfo, COL_INFO,
14610                                         "%s %s",
14611                                         decode_smb_name(cmd),
14612                                         (si->request)? "Request" : "Response");
14613                         } else {
14614                                 col_append_fstr(pinfo->cinfo, COL_INFO,
14615                                         "; %s",
14616                                         decode_smb_name(cmd));
14617                         }
14618
14619                 }
14620
14621                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
14622                         "%s %s (0x%02x)",
14623                         decode_smb_name(cmd),
14624                         (si->request)?"Request":"Response",
14625                         cmd);
14626
14627                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
14628
14629                 dissector = (si->request)?
14630                         smb_dissector[cmd].request:smb_dissector[cmd].response;
14631
14632                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
14633                 proto_item_set_end(cmd_item, tvb, offset);
14634         }
14635         return offset;
14636 }
14637
14638
14639 /* NOTE: this value_string array will also be used to access data directly by
14640  * index instead of val_to_str() since
14641  * 1, the array will always span every value from 0x00 to 0xff and
14642  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
14643  * This means that this value_string array MUST always
14644  * 1, contain all entries 0x00 to 0xff
14645  * 2, all entries must be in order.
14646  */
14647 const value_string smb_cmd_vals[] = {
14648   { 0x00, "Create Directory" },
14649   { 0x01, "Delete Directory" },
14650   { 0x02, "Open" },
14651   { 0x03, "Create" },
14652   { 0x04, "Close" },
14653   { 0x05, "Flush" },
14654   { 0x06, "Delete" },
14655   { 0x07, "Rename" },
14656   { 0x08, "Query Information" },
14657   { 0x09, "Set Information" },
14658   { 0x0A, "Read" },
14659   { 0x0B, "Write" },
14660   { 0x0C, "Lock Byte Range" },
14661   { 0x0D, "Unlock Byte Range" },
14662   { 0x0E, "Create Temp" },
14663   { 0x0F, "Create New" },
14664   { 0x10, "Check Directory" },
14665   { 0x11, "Process Exit" },
14666   { 0x12, "Seek" },
14667   { 0x13, "Lock And Read" },
14668   { 0x14, "Write And Unlock" },
14669   { 0x15, "unknown-0x15" },
14670   { 0x16, "unknown-0x16" },
14671   { 0x17, "unknown-0x17" },
14672   { 0x18, "unknown-0x18" },
14673   { 0x19, "unknown-0x19" },
14674   { 0x1A, "Read Raw" },
14675   { 0x1B, "Read MPX" },
14676   { 0x1C, "Read MPX Secondary" },
14677   { 0x1D, "Write Raw" },
14678   { 0x1E, "Write MPX" },
14679   { 0x1F, "Write MPX Secondary" },
14680   { 0x20, "Write Complete" },
14681   { 0x21, "unknown-0x21" },
14682   { 0x22, "Set Information2" },
14683   { 0x23, "Query Information2" },
14684   { 0x24, "Locking AndX" },
14685   { 0x25, "Trans" },
14686   { 0x26, "Trans Secondary" },
14687   { 0x27, "IOCTL" },
14688   { 0x28, "IOCTL Secondary" },
14689   { 0x29, "Copy" },
14690   { 0x2A, "Move" },
14691   { 0x2B, "Echo" },
14692   { 0x2C, "Write And Close" },
14693   { 0x2D, "Open AndX" },
14694   { 0x2E, "Read AndX" },
14695   { 0x2F, "Write AndX" },
14696   { 0x30, "unknown-0x30" },
14697   { 0x31, "Close And Tree Disconnect" },
14698   { 0x32, "Trans2" },
14699   { 0x33, "Trans2 Secondary" },
14700   { 0x34, "Find Close2" },
14701   { 0x35, "Find Notify Close" },
14702   { 0x36, "unknown-0x36" },
14703   { 0x37, "unknown-0x37" },
14704   { 0x38, "unknown-0x38" },
14705   { 0x39, "unknown-0x39" },
14706   { 0x3A, "unknown-0x3A" },
14707   { 0x3B, "unknown-0x3B" },
14708   { 0x3C, "unknown-0x3C" },
14709   { 0x3D, "unknown-0x3D" },
14710   { 0x3E, "unknown-0x3E" },
14711   { 0x3F, "unknown-0x3F" },
14712   { 0x40, "unknown-0x40" },
14713   { 0x41, "unknown-0x41" },
14714   { 0x42, "unknown-0x42" },
14715   { 0x43, "unknown-0x43" },
14716   { 0x44, "unknown-0x44" },
14717   { 0x45, "unknown-0x45" },
14718   { 0x46, "unknown-0x46" },
14719   { 0x47, "unknown-0x47" },
14720   { 0x48, "unknown-0x48" },
14721   { 0x49, "unknown-0x49" },
14722   { 0x4A, "unknown-0x4A" },
14723   { 0x4B, "unknown-0x4B" },
14724   { 0x4C, "unknown-0x4C" },
14725   { 0x4D, "unknown-0x4D" },
14726   { 0x4E, "unknown-0x4E" },
14727   { 0x4F, "unknown-0x4F" },
14728   { 0x50, "unknown-0x50" },
14729   { 0x51, "unknown-0x51" },
14730   { 0x52, "unknown-0x52" },
14731   { 0x53, "unknown-0x53" },
14732   { 0x54, "unknown-0x54" },
14733   { 0x55, "unknown-0x55" },
14734   { 0x56, "unknown-0x56" },
14735   { 0x57, "unknown-0x57" },
14736   { 0x58, "unknown-0x58" },
14737   { 0x59, "unknown-0x59" },
14738   { 0x5A, "unknown-0x5A" },
14739   { 0x5B, "unknown-0x5B" },
14740   { 0x5C, "unknown-0x5C" },
14741   { 0x5D, "unknown-0x5D" },
14742   { 0x5E, "unknown-0x5E" },
14743   { 0x5F, "unknown-0x5F" },
14744   { 0x60, "unknown-0x60" },
14745   { 0x61, "unknown-0x61" },
14746   { 0x62, "unknown-0x62" },
14747   { 0x63, "unknown-0x63" },
14748   { 0x64, "unknown-0x64" },
14749   { 0x65, "unknown-0x65" },
14750   { 0x66, "unknown-0x66" },
14751   { 0x67, "unknown-0x67" },
14752   { 0x68, "unknown-0x68" },
14753   { 0x69, "unknown-0x69" },
14754   { 0x6A, "unknown-0x6A" },
14755   { 0x6B, "unknown-0x6B" },
14756   { 0x6C, "unknown-0x6C" },
14757   { 0x6D, "unknown-0x6D" },
14758   { 0x6E, "unknown-0x6E" },
14759   { 0x6F, "unknown-0x6F" },
14760   { 0x70, "Tree Connect" },
14761   { 0x71, "Tree Disconnect" },
14762   { 0x72, "Negotiate Protocol" },
14763   { 0x73, "Session Setup AndX" },
14764   { 0x74, "Logoff AndX" },
14765   { 0x75, "Tree Connect AndX" },
14766   { 0x76, "unknown-0x76" },
14767   { 0x77, "unknown-0x77" },
14768   { 0x78, "unknown-0x78" },
14769   { 0x79, "unknown-0x79" },
14770   { 0x7A, "unknown-0x7A" },
14771   { 0x7B, "unknown-0x7B" },
14772   { 0x7C, "unknown-0x7C" },
14773   { 0x7D, "unknown-0x7D" },
14774   { 0x7E, "unknown-0x7E" },
14775   { 0x7F, "unknown-0x7F" },
14776   { 0x80, "Query Information Disk" },
14777   { 0x81, "Search" },
14778   { 0x82, "Find" },
14779   { 0x83, "Find Unique" },
14780   { 0x84, "Find Close" },
14781   { 0x85, "unknown-0x85" },
14782   { 0x86, "unknown-0x86" },
14783   { 0x87, "unknown-0x87" },
14784   { 0x88, "unknown-0x88" },
14785   { 0x89, "unknown-0x89" },
14786   { 0x8A, "unknown-0x8A" },
14787   { 0x8B, "unknown-0x8B" },
14788   { 0x8C, "unknown-0x8C" },
14789   { 0x8D, "unknown-0x8D" },
14790   { 0x8E, "unknown-0x8E" },
14791   { 0x8F, "unknown-0x8F" },
14792   { 0x90, "unknown-0x90" },
14793   { 0x91, "unknown-0x91" },
14794   { 0x92, "unknown-0x92" },
14795   { 0x93, "unknown-0x93" },
14796   { 0x94, "unknown-0x94" },
14797   { 0x95, "unknown-0x95" },
14798   { 0x96, "unknown-0x96" },
14799   { 0x97, "unknown-0x97" },
14800   { 0x98, "unknown-0x98" },
14801   { 0x99, "unknown-0x99" },
14802   { 0x9A, "unknown-0x9A" },
14803   { 0x9B, "unknown-0x9B" },
14804   { 0x9C, "unknown-0x9C" },
14805   { 0x9D, "unknown-0x9D" },
14806   { 0x9E, "unknown-0x9E" },
14807   { 0x9F, "unknown-0x9F" },
14808   { 0xA0, "NT Trans" },
14809   { 0xA1, "NT Trans Secondary" },
14810   { 0xA2, "NT Create AndX" },
14811   { 0xA3, "unknown-0xA3" },
14812   { 0xA4, "NT Cancel" },
14813   { 0xA5, "NT Rename" },
14814   { 0xA6, "unknown-0xA6" },
14815   { 0xA7, "unknown-0xA7" },
14816   { 0xA8, "unknown-0xA8" },
14817   { 0xA9, "unknown-0xA9" },
14818   { 0xAA, "unknown-0xAA" },
14819   { 0xAB, "unknown-0xAB" },
14820   { 0xAC, "unknown-0xAC" },
14821   { 0xAD, "unknown-0xAD" },
14822   { 0xAE, "unknown-0xAE" },
14823   { 0xAF, "unknown-0xAF" },
14824   { 0xB0, "unknown-0xB0" },
14825   { 0xB1, "unknown-0xB1" },
14826   { 0xB2, "unknown-0xB2" },
14827   { 0xB3, "unknown-0xB3" },
14828   { 0xB4, "unknown-0xB4" },
14829   { 0xB5, "unknown-0xB5" },
14830   { 0xB6, "unknown-0xB6" },
14831   { 0xB7, "unknown-0xB7" },
14832   { 0xB8, "unknown-0xB8" },
14833   { 0xB9, "unknown-0xB9" },
14834   { 0xBA, "unknown-0xBA" },
14835   { 0xBB, "unknown-0xBB" },
14836   { 0xBC, "unknown-0xBC" },
14837   { 0xBD, "unknown-0xBD" },
14838   { 0xBE, "unknown-0xBE" },
14839   { 0xBF, "unknown-0xBF" },
14840   { 0xC0, "Open Print File" },
14841   { 0xC1, "Write Print File" },
14842   { 0xC2, "Close Print File" },
14843   { 0xC3, "Get Print Queue" },
14844   { 0xC4, "unknown-0xC4" },
14845   { 0xC5, "unknown-0xC5" },
14846   { 0xC6, "unknown-0xC6" },
14847   { 0xC7, "unknown-0xC7" },
14848   { 0xC8, "unknown-0xC8" },
14849   { 0xC9, "unknown-0xC9" },
14850   { 0xCA, "unknown-0xCA" },
14851   { 0xCB, "unknown-0xCB" },
14852   { 0xCC, "unknown-0xCC" },
14853   { 0xCD, "unknown-0xCD" },
14854   { 0xCE, "unknown-0xCE" },
14855   { 0xCF, "unknown-0xCF" },
14856   { 0xD0, "Send Single Block Message" },
14857   { 0xD1, "Send Broadcast Message" },
14858   { 0xD2, "Forward User Name" },
14859   { 0xD3, "Cancel Forward" },
14860   { 0xD4, "Get Machine Name" },
14861   { 0xD5, "Send Start of Multi-block Message" },
14862   { 0xD6, "Send End of Multi-block Message" },
14863   { 0xD7, "Send Text of Multi-block Message" },
14864   { 0xD8, "SMBreadbulk" },
14865   { 0xD9, "SMBwritebulk" },
14866   { 0xDA, "SMBwritebulkdata" },
14867   { 0xDB, "unknown-0xDB" },
14868   { 0xDC, "unknown-0xDC" },
14869   { 0xDD, "unknown-0xDD" },
14870   { 0xDE, "unknown-0xDE" },
14871   { 0xDF, "unknown-0xDF" },
14872   { 0xE0, "unknown-0xE0" },
14873   { 0xE1, "unknown-0xE1" },
14874   { 0xE2, "unknown-0xE2" },
14875   { 0xE3, "unknown-0xE3" },
14876   { 0xE4, "unknown-0xE4" },
14877   { 0xE5, "unknown-0xE5" },
14878   { 0xE6, "unknown-0xE6" },
14879   { 0xE7, "unknown-0xE7" },
14880   { 0xE8, "unknown-0xE8" },
14881   { 0xE9, "unknown-0xE9" },
14882   { 0xEA, "unknown-0xEA" },
14883   { 0xEB, "unknown-0xEB" },
14884   { 0xEC, "unknown-0xEC" },
14885   { 0xED, "unknown-0xED" },
14886   { 0xEE, "unknown-0xEE" },
14887   { 0xEF, "unknown-0xEF" },
14888   { 0xF0, "unknown-0xF0" },
14889   { 0xF1, "unknown-0xF1" },
14890   { 0xF2, "unknown-0xF2" },
14891   { 0xF3, "unknown-0xF3" },
14892   { 0xF4, "unknown-0xF4" },
14893   { 0xF5, "unknown-0xF5" },
14894   { 0xF6, "unknown-0xF6" },
14895   { 0xF7, "unknown-0xF7" },
14896   { 0xF8, "unknown-0xF8" },
14897   { 0xF9, "unknown-0xF9" },
14898   { 0xFA, "unknown-0xFA" },
14899   { 0xFB, "unknown-0xFB" },
14900   { 0xFC, "unknown-0xFC" },
14901   { 0xFD, "unknown-0xFD" },
14902   { 0xFE, "SMBinvalid" },
14903   { 0xFF, "unknown-0xFF" },
14904   { 0x00, NULL },
14905 };
14906
14907 static char *decode_smb_name(unsigned char cmd)
14908 {
14909   return(smb_cmd_vals[cmd].strptr);
14910 }
14911
14912
14913
14914 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14915  * Everything TVBUFFIFIED above this line
14916  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
14917
14918
14919 static void
14920 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
14921 {
14922         conv_tables_t *ct = ctarg;
14923
14924         if (ct->unmatched)
14925                 g_hash_table_destroy(ct->unmatched);
14926         if (ct->matched)
14927                 g_hash_table_destroy(ct->matched);
14928         if (ct->tid_service)
14929                 g_hash_table_destroy(ct->tid_service);
14930 }
14931
14932 static void
14933 smb_init_protocol(void)
14934 {
14935         if (smb_saved_info_key_chunk)
14936                 g_mem_chunk_destroy(smb_saved_info_key_chunk);
14937         if (smb_saved_info_chunk)
14938                 g_mem_chunk_destroy(smb_saved_info_chunk);
14939         if (smb_nt_transact_info_chunk)
14940                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
14941         if (smb_transact2_info_chunk)
14942                 g_mem_chunk_destroy(smb_transact2_info_chunk);
14943         if (smb_transact_info_chunk)
14944                 g_mem_chunk_destroy(smb_transact_info_chunk);
14945
14946         /*
14947          * Free the hash tables attached to the conversation table
14948          * structures, and then free the list of conversation table
14949          * data structures (which doesn't free the data structures
14950          * themselves; that's done by destroying the chunk from
14951          * which they were allocated).
14952          */
14953         if (conv_tables) {
14954                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
14955                 g_slist_free(conv_tables);
14956                 conv_tables = NULL;
14957         }
14958
14959         /*
14960          * Now destroy the chunk from which the conversation table
14961          * structures were allocated.
14962          */
14963         if (conv_tables_chunk)
14964                 g_mem_chunk_destroy(conv_tables_chunk);
14965
14966         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
14967             sizeof(smb_saved_info_t),
14968             smb_saved_info_init_count * sizeof(smb_saved_info_t),
14969             G_ALLOC_ONLY);
14970         smb_saved_info_key_chunk = g_mem_chunk_new("smb_saved_info_key_chunk",
14971             sizeof(smb_saved_info_key_t),
14972             smb_saved_info_init_count * sizeof(smb_saved_info_key_t),
14973             G_ALLOC_ONLY);
14974         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
14975             sizeof(smb_nt_transact_info_t),
14976             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
14977             G_ALLOC_ONLY);
14978         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
14979             sizeof(smb_transact2_info_t),
14980             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
14981             G_ALLOC_ONLY);
14982         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
14983             sizeof(smb_transact_info_t),
14984             smb_transact_info_init_count * sizeof(smb_transact_info_t),
14985             G_ALLOC_ONLY);
14986         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
14987             sizeof(conv_tables_t),
14988             conv_tables_count * sizeof(conv_tables_t),
14989             G_ALLOC_ONLY);
14990 }
14991
14992 static const value_string errcls_types[] = {
14993   { SMB_SUCCESS, "Success"},
14994   { SMB_ERRDOS, "DOS Error"},
14995   { SMB_ERRSRV, "Server Error"},
14996   { SMB_ERRHRD, "Hardware Error"},
14997   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
14998   { 0, NULL }
14999 };
15000
15001 const value_string DOS_errors[] = {
15002   {0, "Success"},
15003   {SMBE_insufficientbuffer, "Insufficient buffer"},
15004   {SMBE_badfunc, "Invalid function (or system call)"},
15005   {SMBE_badfile, "File not found (pathname error)"},
15006   {SMBE_badpath, "Directory not found"},
15007   {SMBE_nofids, "Too many open files"},
15008   {SMBE_noaccess, "Access denied"},
15009   {SMBE_badfid, "Invalid fid"},
15010   {SMBE_nomem,  "Out of memory"},
15011   {SMBE_badmem, "Invalid memory block address"},
15012   {SMBE_badenv, "Invalid environment"},
15013   {SMBE_badaccess, "Invalid open mode"},
15014   {SMBE_baddata, "Invalid data (only from ioctl call)"},
15015   {SMBE_res, "Reserved error code?"},
15016   {SMBE_baddrive, "Invalid drive"},
15017   {SMBE_remcd, "Attempt to delete current directory"},
15018   {SMBE_diffdevice, "Rename/move across different filesystems"},
15019   {SMBE_nofiles, "No more files found in file search"},
15020   {SMBE_badshare, "Share mode on file conflict with open mode"},
15021   {SMBE_lock, "Lock request conflicts with existing lock"},
15022   {SMBE_unsup, "Request unsupported, returned by Win 95"},
15023   {SMBE_nosuchshare, "Requested share does not exist"},
15024   {SMBE_filexists, "File in operation already exists"},
15025   {SMBE_cannotopen, "Cannot open the file specified"},
15026   {SMBE_unknownlevel, "Unknown info level"},
15027   {SMBE_invalidname, "Invalid name"},
15028   {SMBE_badpipe, "Named pipe invalid"},
15029   {SMBE_pipebusy, "All instances of pipe are busy"},
15030   {SMBE_pipeclosing, "Named pipe close in progress"},
15031   {SMBE_notconnected, "No process on other end of named pipe"},
15032   {SMBE_moredata, "More data to be returned"},
15033   {SMBE_baddirectory,  "Invalid directory name in a path."},
15034   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
15035   {SMBE_eas_nsup, "Extended attributes not supported"},
15036   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
15037   {SMBE_unknownipc, "Unknown IPC Operation"},
15038   {SMBE_noipc, "Don't support ipc"},
15039   {SMBE_alreadyexists, "File already exists"},
15040   {SMBE_unknownprinterdriver, "Unknown printer driver"},
15041   {SMBE_invalidprintername, "Invalid printer name"},
15042   {SMBE_printeralreadyexists, "Printer already exists"},
15043   {SMBE_invaliddatatype, "Invalid data type"},
15044   {SMBE_invalidenvironment, "Invalid environment"},
15045   {SMBE_printerdriverinuse, "Printer driver in use"},
15046   {SMBE_invalidparam, "Invalid parameter"},
15047   {SMBE_invalidformsize, "Invalid form size"},
15048   {SMBE_invalidsecuritydescriptor, "Invalid security descriptor"},
15049   {SMBE_invalidowner, "Invalid owner"},
15050   {SMBE_nomoreitems, "No more items"},
15051   {SMBE_serverunavailable, "Server unavailable"},
15052   {0, NULL}
15053   };
15054
15055 /* Error codes for the ERRSRV class */
15056
15057 static const value_string SRV_errors[] = {
15058   {SMBE_error, "Non specific error code"},
15059   {SMBE_badpw, "Bad password"},
15060   {SMBE_badtype, "Reserved"},
15061   {SMBE_access, "No permissions to perform the requested operation"},
15062   {SMBE_invnid, "TID invalid"},
15063   {SMBE_invnetname, "Invalid network name. Service not found"},
15064   {SMBE_invdevice, "Invalid device"},
15065   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
15066   {SMBE_qfull, "Print queue full"},
15067   {SMBE_qtoobig, "Queued item too big"},
15068   {SMBE_qeof, "EOF on print queue dump"},
15069   {SMBE_invpfid, "Invalid print file in smb_fid"},
15070   {SMBE_smbcmd, "Unrecognised command"},
15071   {SMBE_srverror, "SMB server internal error"},
15072   {SMBE_filespecs, "Fid and pathname invalid combination"},
15073   {SMBE_badlink, "Bad link in request ???"},
15074   {SMBE_badpermits, "Access specified for a file is not valid"},
15075   {SMBE_badpid, "Bad process id in request"},
15076   {SMBE_setattrmode, "Attribute mode invalid"},
15077   {SMBE_paused, "Message server paused"},
15078   {SMBE_msgoff, "Not receiving messages"},
15079   {SMBE_noroom, "No room for message"},
15080   {SMBE_rmuns, "Too many remote usernames"},
15081   {SMBE_timeout, "Operation timed out"},
15082   {SMBE_noresource, "No resources currently available for request."},
15083   {SMBE_toomanyuids, "Too many userids"},
15084   {SMBE_baduid, "Bad userid"},
15085   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
15086   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
15087   {SMBE_contMPX, "Resume MPX mode"},
15088   {SMBE_badPW, "Bad Password???"},
15089   {SMBE_nosupport, "Operation not supported"},
15090   { 0, NULL}
15091 };
15092
15093 /* Error codes for the ERRHRD class */
15094
15095 static const value_string HRD_errors[] = {
15096   {SMBE_nowrite, "Read only media"},
15097   {SMBE_badunit, "Unknown device"},
15098   {SMBE_notready, "Drive not ready"},
15099   {SMBE_badcmd, "Unknown command"},
15100   {SMBE_data, "Data (CRC) error"},
15101   {SMBE_badreq, "Bad request structure length"},
15102   {SMBE_seek, "Seek error"},
15103   {SMBE_badmedia, "Unknown media type"},
15104   {SMBE_badsector, "Sector not found"},
15105   {SMBE_nopaper, "Printer out of paper"},
15106   {SMBE_write, "Write fault"},
15107   {SMBE_read, "Read fault"},
15108   {SMBE_general, "General failure"},
15109   {SMBE_badshare, "A open conflicts with an existing open"},
15110   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
15111   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
15112   {SMBE_FCBunavail, "No FCBs are available to process request"},
15113   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
15114   {SMBE_diskfull, "Disk full???"},
15115   {0, NULL}
15116 };
15117
15118 static char *decode_smb_error(guint8 errcls, guint16 errcode)
15119 {
15120
15121   switch (errcls) {
15122
15123   case SMB_SUCCESS:
15124
15125     return("No Error");   /* No error ??? */
15126     break;
15127
15128   case SMB_ERRDOS:
15129
15130     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
15131     break;
15132
15133   case SMB_ERRSRV:
15134
15135     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
15136     break;
15137
15138   case SMB_ERRHRD:
15139
15140     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
15141     break;
15142
15143   default:
15144
15145     return("Unknown error class!");
15146
15147   }
15148
15149 }
15150
15151
15152 /* These are the MS country codes from
15153
15154         http://www.unicode.org/unicode/onlinedat/countries.html
15155
15156    For countries that share the same number, I choose to use only the
15157    name of the largest country. Apologies for this. If this offends you,
15158    here is the table to change that.
15159
15160    This also includes the code of 0 for "Default", which isn't in
15161    that list, but is in Microsoft's SDKs and the Cygnus "winnls.h"
15162    header file.  Presumably it means "don't override the setting
15163    on the user's machine".
15164
15165    Future versions of Microsoft's "winnls.h" header file might include
15166    additional codes; the current version matches the Unicode Consortium's
15167    table.
15168 */
15169 const value_string ms_country_codes[] = {
15170         {  0,   "Default"},
15171         {  1,   "USA"},
15172         {  2,   "Canada"},
15173         {  7,   "Russia"},
15174         { 20,   "Egypt"},
15175         { 27,   "South Africa"},
15176         { 30,   "Greece"},
15177         { 31,   "Netherlands"},
15178         { 32,   "Belgium"},
15179         { 33,   "France"},
15180         { 34,   "Spain"},
15181         { 36,   "Hungary"},
15182         { 39,   "Italy"},
15183         { 40,   "Romania"},
15184         { 41,   "Switzerland"},
15185         { 43,   "Austria"},
15186         { 44,   "United Kingdom"},
15187         { 45,   "Denmark"},
15188         { 46,   "Sweden"},
15189         { 47,   "Norway"},
15190         { 48,   "Poland"},
15191         { 49,   "Germany"},
15192         { 51,   "Peru"},
15193         { 52,   "Mexico"},
15194         { 54,   "Argentina"},
15195         { 55,   "Brazil"},
15196         { 56,   "Chile"},
15197         { 57,   "Colombia"},
15198         { 58,   "Venezuela"},
15199         { 60,   "Malaysia"},
15200         { 61,   "Australia"},
15201         { 62,   "Indonesia"},
15202         { 63,   "Philippines"},
15203         { 64,   "New Zealand"},
15204         { 65,   "Singapore"},
15205         { 66,   "Thailand"},
15206         { 81,   "Japan"},
15207         { 82,   "South Korea"},
15208         { 84,   "Viet Nam"},
15209         { 86,   "China"},
15210         { 90,   "Turkey"},
15211         { 91,   "India"},
15212         { 92,   "Pakistan"},
15213         {212,   "Morocco"},
15214         {213,   "Algeria"},
15215         {216,   "Tunisia"},
15216         {218,   "Libya"},
15217         {254,   "Kenya"},
15218         {263,   "Zimbabwe"},
15219         {298,   "Faroe Islands"},
15220         {351,   "Portugal"},
15221         {352,   "Luxembourg"},
15222         {353,   "Ireland"},
15223         {354,   "Iceland"},
15224         {355,   "Albania"},
15225         {358,   "Finland"},
15226         {359,   "Bulgaria"},
15227         {370,   "Lithuania"},
15228         {371,   "Latvia"},
15229         {372,   "Estonia"},
15230         {374,   "Armenia"},
15231         {375,   "Belarus"},
15232         {380,   "Ukraine"},
15233         {381,   "Serbia"},
15234         {385,   "Croatia"},
15235         {386,   "Slovenia"},
15236         {389,   "Macedonia"},
15237         {420,   "Czech Republic"},
15238         {421,   "Slovak Republic"},
15239         {501,   "Belize"},
15240         {502,   "Guatemala"},
15241         {503,   "El Salvador"},
15242         {504,   "Honduras"},
15243         {505,   "Nicaragua"},
15244         {506,   "Costa Rica"},
15245         {507,   "Panama"},
15246         {591,   "Bolivia"},
15247         {593,   "Ecuador"},
15248         {595,   "Paraguay"},
15249         {598,   "Uruguay"},
15250         {673,   "Brunei Darussalam"},
15251         {852,   "Hong Kong"},
15252         {853,   "Macau"},
15253         {886,   "Taiwan"},
15254         {960,   "Maldives"},
15255         {961,   "Lebanon"},
15256         {962,   "Jordan"},
15257         {963,   "Syria"},
15258         {964,   "Iraq"},
15259         {965,   "Kuwait"},
15260         {966,   "Saudi Arabia"},
15261         {967,   "Yemen"},
15262         {968,   "Oman"},
15263         {971,   "United Arab Emirates"},
15264         {972,   "Israel"},
15265         {973,   "Bahrain"},
15266         {974,   "Qatar"},
15267         {976,   "Mongolia"},
15268         {981,   "Iran"},
15269         {994,   "Azerbaijan"},
15270         {995,   "Georgia"},
15271         {996,   "Kyrgyzstan"},
15272
15273         {0,     NULL}
15274 };
15275
15276 /*
15277  * NT error codes.
15278  *
15279  * From
15280  *
15281  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
15282  */
15283 const value_string NT_errors[] = {
15284   { 0x00000000, "STATUS_SUCCESS" },
15285   { 0x00000000, "STATUS_WAIT_0" },
15286   { 0x00000001, "STATUS_WAIT_1" },
15287   { 0x00000002, "STATUS_WAIT_2" },
15288   { 0x00000003, "STATUS_WAIT_3" },
15289   { 0x0000003F, "STATUS_WAIT_63" },
15290   { 0x00000080, "STATUS_ABANDONED" },
15291   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
15292   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
15293   { 0x000000C0, "STATUS_USER_APC" },
15294   { 0x00000100, "STATUS_KERNEL_APC" },
15295   { 0x00000101, "STATUS_ALERTED" },
15296   { 0x00000102, "STATUS_TIMEOUT" },
15297   { 0x00000103, "STATUS_PENDING" },
15298   { 0x00000104, "STATUS_REPARSE" },
15299   { 0x00000105, "STATUS_MORE_ENTRIES" },
15300   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
15301   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
15302   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
15303   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
15304   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
15305   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
15306   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
15307   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
15308   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
15309   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
15310   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
15311   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
15312   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
15313   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
15314   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
15315   { 0x00000116, "STATUS_CRASH_DUMP" },
15316   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
15317   { 0x00000118, "STATUS_REPARSE_OBJECT" },
15318   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
15319   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
15320   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
15321   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
15322   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
15323   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
15324   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
15325   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
15326   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
15327   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
15328   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
15329   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
15330   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
15331   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
15332   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
15333   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
15334   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
15335   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
15336   { 0x40000012, "STATUS_EVENT_DONE" },
15337   { 0x40000013, "STATUS_EVENT_PENDING" },
15338   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
15339   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
15340   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
15341   { 0x40000017, "STATUS_WAS_UNLOCKED" },
15342   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
15343   { 0x40000019, "STATUS_WAS_LOCKED" },
15344   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
15345   { 0x4000001B, "STATUS_ALREADY_WIN32" },
15346   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
15347   { 0x4000001D, "STATUS_WX86_CONTINUE" },
15348   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
15349   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
15350   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
15351   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
15352   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
15353   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
15354   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
15355   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
15356   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
15357   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
15358   { 0x80000003, "STATUS_BREAKPOINT" },
15359   { 0x80000004, "STATUS_SINGLE_STEP" },
15360   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
15361   { 0x80000006, "STATUS_NO_MORE_FILES" },
15362   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
15363   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
15364   { 0x8000000B, "STATUS_NO_INHERITANCE" },
15365   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
15366   { 0x8000000D, "STATUS_PARTIAL_COPY" },
15367   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
15368   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
15369   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
15370   { 0x80000011, "STATUS_DEVICE_BUSY" },
15371   { 0x80000012, "STATUS_NO_MORE_EAS" },
15372   { 0x80000013, "STATUS_INVALID_EA_NAME" },
15373   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
15374   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
15375   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
15376   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
15377   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
15378   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
15379   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
15380   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
15381   { 0x8000001D, "STATUS_BUS_RESET" },
15382   { 0x8000001E, "STATUS_END_OF_MEDIA" },
15383   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
15384   { 0x80000020, "STATUS_MEDIA_CHECK" },
15385   { 0x80000021, "STATUS_SETMARK_DETECTED" },
15386   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
15387   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
15388   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
15389   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
15390   { 0x80000026, "STATUS_LONGJUMP" },
15391   { 0x80040111, "MAPI_E_LOGON_FAILED" },
15392   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
15393   { 0x80090301, "SEC_E_INVALID_HANDLE" },
15394   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
15395   { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
15396   { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
15397   { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
15398   { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
15399   { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
15400   { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
15401   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
15402   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
15403   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
15404   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
15405   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
15406   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
15407   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
15408   { 0xC0000008, "STATUS_INVALID_HANDLE" },
15409   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
15410   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
15411   { 0xC000000B, "STATUS_INVALID_CID" },
15412   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
15413   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
15414   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
15415   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
15416   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
15417   { 0xC0000011, "STATUS_END_OF_FILE" },
15418   { 0xC0000012, "STATUS_WRONG_VOLUME" },
15419   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
15420   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
15421   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
15422   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
15423   { 0xC0000017, "STATUS_NO_MEMORY" },
15424   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
15425   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
15426   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
15427   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
15428   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
15429   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
15430   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
15431   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
15432   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
15433   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
15434   { 0xC0000022, "STATUS_ACCESS_DENIED" },
15435   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
15436   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
15437   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
15438   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
15439   { 0xC0000027, "STATUS_UNWIND" },
15440   { 0xC0000028, "STATUS_BAD_STACK" },
15441   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
15442   { 0xC000002A, "STATUS_NOT_LOCKED" },
15443   { 0xC000002B, "STATUS_PARITY_ERROR" },
15444   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
15445   { 0xC000002D, "STATUS_NOT_COMMITTED" },
15446   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
15447   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
15448   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
15449   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
15450   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
15451   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
15452   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
15453   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
15454   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
15455   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
15456   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
15457   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
15458   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
15459   { 0xC000003C, "STATUS_DATA_OVERRUN" },
15460   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
15461   { 0xC000003E, "STATUS_DATA_ERROR" },
15462   { 0xC000003F, "STATUS_CRC_ERROR" },
15463   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
15464   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
15465   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
15466   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
15467   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
15468   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
15469   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
15470   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
15471   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
15472   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
15473   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
15474   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
15475   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
15476   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
15477   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
15478   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
15479   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
15480   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
15481   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
15482   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
15483   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
15484   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
15485   { 0xC0000056, "STATUS_DELETE_PENDING" },
15486   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
15487   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
15488   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
15489   { 0xC000005A, "STATUS_INVALID_OWNER" },
15490   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
15491   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
15492   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
15493   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
15494   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
15495   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
15496   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
15497   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
15498   { 0xC0000063, "STATUS_USER_EXISTS" },
15499   { 0xC0000064, "STATUS_NO_SUCH_USER" },
15500   { 0xC0000065, "STATUS_GROUP_EXISTS" },
15501   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
15502   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
15503   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
15504   { 0xC0000069, "STATUS_LAST_ADMIN" },
15505   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
15506   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
15507   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
15508   { 0xC000006D, "STATUS_LOGON_FAILURE" },
15509   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
15510   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
15511   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
15512   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
15513   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
15514   { 0xC0000073, "STATUS_NONE_MAPPED" },
15515   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
15516   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
15517   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
15518   { 0xC0000077, "STATUS_INVALID_ACL" },
15519   { 0xC0000078, "STATUS_INVALID_SID" },
15520   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
15521   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
15522   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
15523   { 0xC000007C, "STATUS_NO_TOKEN" },
15524   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
15525   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
15526   { 0xC000007F, "STATUS_DISK_FULL" },
15527   { 0xC0000080, "STATUS_SERVER_DISABLED" },
15528   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
15529   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
15530   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
15531   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
15532   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
15533   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
15534   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
15535   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
15536   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
15537   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
15538   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
15539   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
15540   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
15541   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
15542   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
15543   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
15544   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
15545   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
15546   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
15547   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
15548   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
15549   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
15550   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
15551   { 0xC0000098, "STATUS_FILE_INVALID" },
15552   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
15553   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
15554   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
15555   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
15556   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
15557   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
15558   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
15559   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
15560   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
15561   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
15562   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
15563   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
15564   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
15565   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
15566   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
15567   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
15568   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
15569   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
15570   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
15571   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
15572   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
15573   { 0xC00000AE, "STATUS_PIPE_BUSY" },
15574   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
15575   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
15576   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
15577   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
15578   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
15579   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
15580   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
15581   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
15582   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
15583   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
15584   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
15585   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
15586   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
15587   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
15588   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
15589   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
15590   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
15591   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
15592   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
15593   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
15594   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
15595   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
15596   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
15597   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
15598   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
15599   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
15600   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
15601   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
15602   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
15603   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
15604   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
15605   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
15606   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
15607   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
15608   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
15609   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
15610   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
15611   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
15612   { 0xC00000D5, "STATUS_FILE_RENAMED" },
15613   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
15614   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
15615   { 0xC00000D8, "STATUS_CANT_WAIT" },
15616   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
15617   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
15618   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
15619   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
15620   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
15621   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
15622   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
15623   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
15624   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
15625   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
15626   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
15627   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
15628   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
15629   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
15630   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
15631   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
15632   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
15633   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
15634   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
15635   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
15636   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
15637   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
15638   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
15639   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
15640   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
15641   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
15642   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
15643   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
15644   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
15645   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
15646   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
15647   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
15648   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
15649   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
15650   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
15651   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
15652   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
15653   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
15654   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
15655   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
15656   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
15657   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
15658   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
15659   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
15660   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
15661   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
15662   { 0xC0000107, "STATUS_FILES_OPEN" },
15663   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
15664   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
15665   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
15666   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
15667   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
15668   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
15669   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
15670   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
15671   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
15672   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
15673   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
15674   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
15675   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
15676   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
15677   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
15678   { 0xC0000117, "STATUS_NO_LDT" },
15679   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
15680   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
15681   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
15682   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
15683   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
15684   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
15685   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
15686   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
15687   { 0xC0000120, "STATUS_CANCELLED" },
15688   { 0xC0000121, "STATUS_CANNOT_DELETE" },
15689   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
15690   { 0xC0000123, "STATUS_FILE_DELETED" },
15691   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
15692   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
15693   { 0xC0000126, "STATUS_SPECIAL_USER" },
15694   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
15695   { 0xC0000128, "STATUS_FILE_CLOSED" },
15696   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
15697   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
15698   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
15699   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
15700   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
15701   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
15702   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
15703   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
15704   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
15705   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
15706   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
15707   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
15708   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
15709   { 0xC0000136, "STATUS_OPEN_FAILED" },
15710   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
15711   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
15712   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
15713   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
15714   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
15715   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
15716   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
15717   { 0xC000013E, "STATUS_LINK_FAILED" },
15718   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
15719   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
15720   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
15721   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
15722   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
15723   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
15724   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
15725   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
15726   { 0xC0000147, "STATUS_NO_PAGEFILE" },
15727   { 0xC0000148, "STATUS_INVALID_LEVEL" },
15728   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
15729   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
15730   { 0xC000014B, "STATUS_PIPE_BROKEN" },
15731   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
15732   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
15733   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
15734   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
15735   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
15736   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
15737   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
15738   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
15739   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
15740   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
15741   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
15742   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
15743   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
15744   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
15745   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
15746   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
15747   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
15748   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
15749   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
15750   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
15751   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
15752   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
15753   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
15754   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
15755   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
15756   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
15757   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
15758   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
15759   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
15760   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
15761   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
15762   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
15763   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
15764   { 0xC000016D, "STATUS_FT_ORPHANING" },
15765   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
15766   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
15767   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
15768   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
15769   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
15770   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
15771   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
15772   { 0xC0000178, "STATUS_NO_MEDIA" },
15773   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
15774   { 0xC000017B, "STATUS_INVALID_MEMBER" },
15775   { 0xC000017C, "STATUS_KEY_DELETED" },
15776   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
15777   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
15778   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
15779   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
15780   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
15781   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
15782   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
15783   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
15784   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
15785   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
15786   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
15787   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
15788   { 0xC0000189, "STATUS_TOO_LATE" },
15789   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
15790   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
15791   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
15792   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
15793   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
15794   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
15795   { 0xC0000190, "STATUS_TRUST_FAILURE" },
15796   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
15797   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
15798   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
15799   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
15800   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
15801   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
15802   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
15803   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
15804   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
15805   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
15806   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
15807   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
15808   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
15809   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
15810   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
15811   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
15812   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
15813   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
15814   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
15815   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
15816   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
15817   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
15818   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
15819   { 0xC000020D, "STATUS_CONNECTION_RESET" },
15820   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
15821   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
15822   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
15823   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
15824   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
15825   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
15826   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
15827   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
15828   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
15829   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
15830   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
15831   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
15832   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
15833   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
15834   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
15835   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
15836   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
15837   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
15838   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
15839   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
15840   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
15841   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
15842   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
15843   { 0xC0000225, "STATUS_NOT_FOUND" },
15844   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
15845   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
15846   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
15847   { 0xC0000229, "STATUS_FAIL_CHECK" },
15848   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
15849   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
15850   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
15851   { 0xC000022D, "STATUS_RETRY" },
15852   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
15853   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
15854   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
15855   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
15856   { 0xC0000232, "STATUS_INVALID_VARIANT" },
15857   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
15858   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
15859   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
15860   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
15861   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
15862   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
15863   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
15864   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
15865   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
15866   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
15867   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
15868   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
15869   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
15870   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
15871   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
15872   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
15873   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
15874   { 0xC0000244, "STATUS_AUDIT_FAILED" },
15875   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
15876   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
15877   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
15878   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
15879   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
15880   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
15881   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
15882   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
15883   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
15884   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
15885   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
15886   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
15887   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
15888   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
15889   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
15890   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
15891   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
15892   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
15893   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
15894   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
15895   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
15896   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
15897   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
15898   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
15899   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
15900   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
15901   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
15902   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
15903   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
15904   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
15905   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
15906   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
15907   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
15908   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
15909   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
15910   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
15911   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
15912   { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
15913   { 0xC0000272, "STATUS_NO_MATCH" },
15914   { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
15915   { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
15916   { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
15917   { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
15918   { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
15919   { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
15920   { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
15921   { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
15922   { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
15923   { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
15924   { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
15925   { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
15926   { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
15927   { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
15928   { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
15929   { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
15930   { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
15931   { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
15932   { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
15933   { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
15934   { 0xC000028E, "STATUS_NO_EFS" },
15935   { 0xC000028F, "STATUS_WRONG_EFS" },
15936   { 0xC0000290, "STATUS_NO_USER_KEYS" },
15937   { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
15938   { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
15939   { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
15940   { 0x40000294, "STATUS_WAKE_SYSTEM" },
15941   { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
15942   { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
15943   { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
15944   { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
15945   { 0xC0000299, "STATUS_SHARED_POLICY" },
15946   { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
15947   { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
15948   { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
15949   { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
15950   { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
15951   { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
15952   { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
15953   { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
15954   { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
15955   { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
15956   { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
15957   { 0xC00002A5, "STATUS_DS_BUSY" },
15958   { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
15959   { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
15960   { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
15961   { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
15962   { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
15963   { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
15964   { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
15965   { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
15966   { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
15967   { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
15968   { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
15969   { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
15970   { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
15971   { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
15972   { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
15973   { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
15974   { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
15975   { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
15976   { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
15977   { 0xC00002B9, "STATUS_NOINTERFACE" },
15978   { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
15979   { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
15980   { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
15981   { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
15982   { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
15983   { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
15984   { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
15985   { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
15986   { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
15987   { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
15988   { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
15989   { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
15990   { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
15991   { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
15992   { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
15993   { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
15994   { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
15995   { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
15996   { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
15997   { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
15998   { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
15999   { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
16000   { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
16001   { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
16002   { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
16003   { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
16004   { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
16005   { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
16006   { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
16007   { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
16008   { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
16009   { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
16010   { 0xC00002E1, "STATUS_DS_CANT_START" },
16011   { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
16012   { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
16013   { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
16014   { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
16015   { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
16016   { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
16017   { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
16018   { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
16019   { 0xC0009898, "STATUS_WOW_ASSERTION" },
16020   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
16021   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
16022   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
16023   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
16024   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
16025   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
16026   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
16027   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
16028   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
16029   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
16030   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
16031   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
16032   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
16033   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
16034   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
16035   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
16036   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
16037   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
16038   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
16039   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
16040   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
16041   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
16042   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
16043   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
16044   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
16045   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
16046   { 0xC002001B, "RPC_NT_CALL_FAILED" },
16047   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
16048   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
16049   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
16050   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
16051   { 0xC0020022, "RPC_NT_INVALID_TAG" },
16052   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
16053   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
16054   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
16055   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
16056   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
16057   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
16058   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
16059   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
16060   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
16061   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
16062   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
16063   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
16064   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
16065   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
16066   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
16067   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
16068   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
16069   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
16070   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
16071   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
16072   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
16073   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
16074   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
16075   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
16076   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
16077   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
16078   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
16079   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
16080   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
16081   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
16082   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
16083   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
16084   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
16085   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
16086   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
16087   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
16088   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
16089   { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
16090   { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
16091   { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
16092   { 0xC002100A, "RPC_P_SEND_FAILED" },
16093   { 0xC002100B, "RPC_P_TIMEOUT" },
16094   { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
16095   { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
16096   { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
16097   { 0xC0021015, "RPC_P_THREAD_LISTENING" },
16098   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
16099   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
16100   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
16101   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
16102   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
16103   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
16104   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
16105   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
16106   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
16107   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
16108   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
16109   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
16110   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
16111   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
16112   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
16113   { 0xC002004C, "EPT_NT_CANT_CREATE" },
16114   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
16115   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
16116   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
16117   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
16118   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
16119   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
16120   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
16121   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
16122   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
16123   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
16124   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
16125   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
16126   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
16127   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
16128   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
16129   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
16130   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
16131   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
16132   { 0,          NULL }
16133 };
16134
16135
16136
16137 static const true_false_string tfs_smb_flags_lock = {
16138         "Lock&Read, Write&Unlock are supported",
16139         "Lock&Read, Write&Unlock are not supported"
16140 };
16141 static const true_false_string tfs_smb_flags_receive_buffer = {
16142         "Receive buffer has been posted",
16143         "Receive buffer has not been posted"
16144 };
16145 static const true_false_string tfs_smb_flags_caseless = {
16146         "Path names are caseless",
16147         "Path names are case sensitive"
16148 };
16149 static const true_false_string tfs_smb_flags_canon = {
16150         "Pathnames are canonicalized",
16151         "Pathnames are not canonicalized"
16152 };
16153 static const true_false_string tfs_smb_flags_oplock = {
16154         "OpLock requested/granted",
16155         "OpLock not requested/granted"
16156 };
16157 static const true_false_string tfs_smb_flags_notify = {
16158         "Notify client on all modifications",
16159         "Notify client only on open"
16160 };
16161 static const true_false_string tfs_smb_flags_response = {
16162         "Message is a response to the client/redirector",
16163         "Message is a request to the server"
16164 };
16165
16166 static int
16167 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16168 {
16169         guint8 mask;
16170         proto_item *item = NULL;
16171         proto_tree *tree = NULL;
16172
16173         mask = tvb_get_guint8(tvb, offset);
16174
16175         if(parent_tree){
16176                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
16177                         "Flags: 0x%02x", mask);
16178                 tree = proto_item_add_subtree(item, ett_smb_flags);
16179         }
16180         proto_tree_add_boolean(tree, hf_smb_flags_response,
16181                 tvb, offset, 1, mask);
16182         proto_tree_add_boolean(tree, hf_smb_flags_notify,
16183                 tvb, offset, 1, mask);
16184         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
16185                 tvb, offset, 1, mask);
16186         proto_tree_add_boolean(tree, hf_smb_flags_canon,
16187                 tvb, offset, 1, mask);
16188         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
16189                 tvb, offset, 1, mask);
16190         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
16191                 tvb, offset, 1, mask);
16192         proto_tree_add_boolean(tree, hf_smb_flags_lock,
16193                 tvb, offset, 1, mask);
16194         offset += 1;
16195         return offset;
16196 }
16197
16198
16199
16200 static const true_false_string tfs_smb_flags2_long_names_allowed = {
16201         "Long file names are allowed in the response",
16202         "Long file names are not allowed in the response"
16203 };
16204 static const true_false_string tfs_smb_flags2_ea = {
16205         "Extended attributes are supported",
16206         "Extended attributes are not supported"
16207 };
16208 static const true_false_string tfs_smb_flags2_sec_sig = {
16209         "Security signatures are supported",
16210         "Security signatures are not supported"
16211 };
16212 static const true_false_string tfs_smb_flags2_long_names_used = {
16213         "Path names in request are long file names",
16214         "Path names in request are not long file names"
16215 };
16216 static const true_false_string tfs_smb_flags2_esn = {
16217         "Extended security negotiation is supported",
16218         "Extended security negotiation is not supported"
16219 };
16220 static const true_false_string tfs_smb_flags2_dfs = {
16221         "Resolve pathnames with Dfs",
16222         "Don't resolve pathnames with Dfs"
16223 };
16224 static const true_false_string tfs_smb_flags2_roe = {
16225         "Permit reads if execute-only",
16226         "Don't permit reads if execute-only"
16227 };
16228 static const true_false_string tfs_smb_flags2_nt_error = {
16229         "Error codes are NT error codes",
16230         "Error codes are DOS error codes"
16231 };
16232 static const true_false_string tfs_smb_flags2_string = {
16233         "Strings are Unicode",
16234         "Strings are ASCII"
16235 };
16236 static int
16237 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16238 {
16239         guint16 mask;
16240         proto_item *item = NULL;
16241         proto_tree *tree = NULL;
16242
16243         mask = tvb_get_letohs(tvb, offset);
16244
16245         if(parent_tree){
16246                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
16247                         "Flags2: 0x%04x", mask);
16248                 tree = proto_item_add_subtree(item, ett_smb_flags2);
16249         }
16250
16251         proto_tree_add_boolean(tree, hf_smb_flags2_string,
16252                 tvb, offset, 2, mask);
16253         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
16254                 tvb, offset, 2, mask);
16255         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
16256                 tvb, offset, 2, mask);
16257         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
16258                 tvb, offset, 2, mask);
16259         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
16260                 tvb, offset, 2, mask);
16261         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
16262                 tvb, offset, 2, mask);
16263         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
16264                 tvb, offset, 2, mask);
16265         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
16266                 tvb, offset, 2, mask);
16267         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
16268                 tvb, offset, 2, mask);
16269
16270         offset += 2;
16271         return offset;
16272 }
16273
16274
16275
16276 #define SMB_FLAGS_DIRN 0x80
16277
16278
16279 static void
16280 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16281 {
16282         int offset = 0;
16283         proto_item *item = NULL, *hitem = NULL;
16284         proto_tree *tree = NULL, *htree = NULL;
16285         guint8          flags;
16286         guint16         flags2;
16287         static smb_info_t       si_arr[20];
16288         static int si_counter=0;
16289         smb_info_t              *si;
16290         smb_saved_info_t *sip = NULL;
16291         smb_saved_info_key_t key;
16292         smb_saved_info_key_t *new_key;
16293         guint32 nt_status = 0;
16294         guint8 errclass = 0;
16295         guint16 errcode = 0;
16296         guint32 pid_mid;
16297         conversation_t *conversation;
16298         nstime_t ns;
16299
16300         si_counter++;
16301         if(si_counter==20){
16302                 si_counter=0;
16303         }
16304         si=&si_arr[si_counter];
16305
16306         top_tree=parent_tree;
16307
16308         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
16309                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
16310         }
16311         if (check_col(pinfo->cinfo, COL_INFO)){
16312                 col_clear(pinfo->cinfo, COL_INFO);
16313         }
16314
16315         /* start off using the local variable, we will allocate a new one if we
16316            need to*/
16317         si->cmd = tvb_get_guint8(tvb, offset+4);
16318         flags = tvb_get_guint8(tvb, offset+9);
16319         /*
16320          * XXX - in some SMB-over-OSI-transport and SMB-over-Vines traffic,
16321          * the direction flag appears never to be set, even for what appear
16322          * to be replies.  Do some SMB servers fail to set that flag,
16323          * under the assumption that the client knows it's a reply because
16324          * it received it?
16325          */
16326         si->request = !(flags&SMB_FLAGS_DIRN);
16327         flags2 = tvb_get_letohs(tvb, offset+10);
16328         if(flags2 & 0x8000){
16329                 si->unicode = TRUE; /* Mark them as Unicode */
16330         } else {
16331                 si->unicode = FALSE;
16332         }
16333         si->tid = tvb_get_letohs(tvb, offset+24);
16334         si->pid = tvb_get_letohs(tvb, offset+26);
16335         si->uid = tvb_get_letohs(tvb, offset+28);
16336         si->mid = tvb_get_letohs(tvb, offset+30);
16337         pid_mid = (si->pid << 16) | si->mid;
16338         si->info_level = -1;
16339         si->info_count = -1;
16340
16341         if (parent_tree) {
16342                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
16343                         -1, FALSE);
16344                 tree = proto_item_add_subtree(item, ett_smb);
16345
16346                 hitem = proto_tree_add_text(tree, tvb, offset, 32,
16347                         "SMB Header");
16348
16349                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
16350         }
16351
16352         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
16353         offset += 4;  /* Skip the marker */
16354
16355         /* find which conversation we are part of and get the tables for that
16356            conversation*/
16357         conversation = find_conversation(&pinfo->src, &pinfo->dst,
16358                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
16359         if(!conversation){
16360                 /* OK this is a new conversation so lets create it */
16361                 conversation = conversation_new(&pinfo->src, &pinfo->dst,
16362                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
16363         }
16364         /* see if we already have the smb data for this conversation */
16365         si->ct=conversation_get_proto_data(conversation, proto_smb);
16366         if(!si->ct){
16367                 /* No, not yet. create it and attach it to the conversation */
16368                 si->ct = g_mem_chunk_alloc(conv_tables_chunk);
16369                 conv_tables = g_slist_prepend(conv_tables, si->ct);
16370                 si->ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
16371                         smb_saved_info_equal_matched);
16372                 si->ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
16373                         smb_saved_info_equal_unmatched);
16374                 si->ct->tid_service=g_hash_table_new(
16375                         smb_saved_info_hash_unmatched,
16376                         smb_saved_info_equal_unmatched);
16377                 conversation_add_proto_data(conversation, proto_smb, si->ct);
16378         }
16379
16380         if( (si->request)
16381             &&  (si->mid==0)
16382             &&  (si->uid==0)
16383             &&  (si->pid==0)
16384             &&  (si->tid==0) ){
16385                 /* this is a broadcast SMB packet, there will not be a reply.
16386                    We dont need to do anything
16387                 */
16388                 si->unidir = TRUE;
16389         } else if( (si->cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
16390                    ||(si->cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
16391                    ||(si->cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
16392                    ||(si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
16393                 /* Ok, we got a special request type. This request is either
16394                    an NT Cancel or a continuation relative to a real request
16395                    in an earlier packet.  In either case, we don't expect any
16396                    responses to this packet.  For continuations, any later
16397                    responses we see really just belong to the original request.
16398                    Anyway, we want to remember this packet somehow and
16399                    remember which original request it is associated with so
16400                    we can say nice things such as "This is a Cancellation to
16401                    the request in frame x", but we don't want the
16402                    request/response matching to get messed up.
16403
16404                    The only thing we do in this case is trying to find which original
16405                    request we match with and insert an entry for this "special"
16406                    request for later reference. We continue to reference the original
16407                    requests smb_saved_info_t but we dont touch it or change anything
16408                    in it.
16409                 */
16410
16411                 si->unidir = TRUE;  /*we dont expect an answer to this one*/
16412
16413                 if(!pinfo->fd->flags.visited){
16414                         /* try to find which original call we match and if we
16415                            find it add us to the matched table. Dont touch
16416                            anything else since we dont want this one to mess
16417                            up the request/response matching. We still consider
16418                            the initial call the real request and this is only
16419                            some sort of continuation.
16420                         */
16421                         /* we only check the unmatched table and assume that the
16422                            last seen MID matching ours is the right one.
16423                            This can fail but is better than nothing
16424                         */
16425                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
16426                         if(sip!=NULL){
16427                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16428                                 new_key->frame = pinfo->fd->num;
16429                                 new_key->pid_mid = pid_mid;
16430                                 g_hash_table_insert(si->ct->matched, new_key,
16431                                     sip);
16432                         }
16433                 } else {
16434                         /* we have seen this packet before; check the
16435                            matching table
16436                         */
16437                         key.frame = pinfo->fd->num;
16438                         key.pid_mid = pid_mid;
16439                         sip=g_hash_table_lookup(si->ct->matched, &key);
16440                         if(sip==NULL){
16441                         /*
16442                           We didn't find it.
16443                           Too bad, unfortunately there is not really much we can
16444                           do now since this means that we never saw the initial
16445                           request.
16446                          */
16447                         }
16448                 }
16449
16450
16451                 if(sip && sip->frame_req){
16452                         switch(si->cmd){
16453                         case SMB_COM_NT_CANCEL:
16454                                 proto_tree_add_uint(htree, hf_smb_cancel_to,
16455                                                     tvb, 0, 0, sip->frame_req);
16456                                 break;
16457                         case SMB_COM_TRANSACTION_SECONDARY:
16458                         case SMB_COM_TRANSACTION2_SECONDARY:
16459                         case SMB_COM_NT_TRANSACT_SECONDARY:
16460                                 proto_tree_add_uint(htree, hf_smb_continuation_to,
16461                                                     tvb, 0, 0, sip->frame_req);
16462                                 break;
16463                         }
16464                 } else {
16465                         switch(si->cmd){
16466                         case SMB_COM_NT_CANCEL:
16467                                 proto_tree_add_text(htree, tvb, 0, 0,
16468                                                     "Cancellation to: <unknown frame>");
16469                                 break;
16470                         case SMB_COM_TRANSACTION_SECONDARY:
16471                         case SMB_COM_TRANSACTION2_SECONDARY:
16472                         case SMB_COM_NT_TRANSACT_SECONDARY:
16473                                 proto_tree_add_text(htree, tvb, 0, 0,
16474                                                     "Continuation to: <unknown frame>");
16475                                 break;
16476                         }
16477                 }
16478         } else { /* normal bidirectional request or response */
16479                 si->unidir = FALSE;
16480
16481                 if(!pinfo->fd->flags.visited){
16482                         /* first see if we find an unmatched smb "equal" to
16483                            the current one
16484                         */
16485                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
16486                         if(sip!=NULL){
16487                                 gboolean cmd_match=FALSE;
16488
16489                                 /*
16490                                  * Make sure the SMB we found was the
16491                                  * same command, or a different command
16492                                  * that's another valid type of reply
16493                                  * to that command.
16494                                  */
16495                                 if(si->cmd==sip->cmd){
16496                                         cmd_match=TRUE;
16497                                 }
16498                                 else if(si->cmd==SMB_COM_NT_CANCEL){
16499                                         cmd_match=TRUE;
16500                                 }
16501                                 else if((si->cmd==SMB_COM_TRANSACTION_SECONDARY)
16502                                      && (sip->cmd==SMB_COM_TRANSACTION)){
16503                                         cmd_match=TRUE;
16504                                 }
16505                                 else if((si->cmd==SMB_COM_TRANSACTION2_SECONDARY)
16506                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
16507                                         cmd_match=TRUE;
16508                                 }
16509                                 else if((si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)
16510                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
16511                                         cmd_match=TRUE;
16512                                 }
16513
16514                                 if( (si->request) || (!cmd_match) ) {
16515                                         /* If we are processing an SMB request but there was already
16516                                            another "identical" smb resuest we had not matched yet.
16517                                            This must mean that either we have a retransmission or that the
16518                                            response to the previous one was lost and the client has reused
16519                                            the MID for this conversation. In either case it's not much more
16520                                            we can do than forget the old request and concentrate on the
16521                                            present one instead.
16522
16523                                            We also do this cleanup if we see that the cmd in the original
16524                                            request in sip->cmd is not compatible with the current cmd.
16525                                            This is to prevent matching errors such as if there were two
16526                                            SMBs of different cmds but with identical MID and PID values and
16527                                            if ethereal lost the first reply and the second request.
16528                                         */
16529                                         g_hash_table_remove(si->ct->unmatched, (void *)pid_mid);
16530                                         sip=NULL; /* XXX should free it as well */
16531                                 } else {
16532                                         /* we have found a response to some request we have seen earlier.
16533                                            What we do now depends on whether this is the first response
16534                                            to that request we see (id frame_res==0) or not.
16535                                         */
16536                                         if(sip->frame_res==0){
16537                                                 /* ok it is the first response we have seen to this packet */
16538                                                 sip->frame_res = pinfo->fd->num;
16539                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16540                                                 new_key->frame = sip->frame_res;
16541                                                 new_key->pid_mid = pid_mid;
16542                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16543                                         } else {
16544                                                 /* We have already seen another response to this MID.
16545                                                    Since the MID in reality is only something like 10 bits
16546                                                    this probably means that we just have a MID that is being
16547                                                    reused due to the small MID space and that this is a new
16548                                                    command we did not see the original request for.
16549                                                 */
16550                                                 sip=NULL;
16551                                         }
16552                                 }
16553                         }
16554                         if(si->request){
16555                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
16556                                 sip->frame_req = pinfo->fd->num;
16557                                 sip->frame_res = 0;
16558                                 sip->req_time.secs=pinfo->fd->abs_secs;
16559                                 sip->req_time.nsecs=pinfo->fd->abs_usecs*1000;
16560                                 sip->flags = 0;
16561                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)
16562                                     == (void *)TID_IPC) {
16563                                         sip->flags |= SMB_SIF_TID_IS_IPC;
16564                                 }
16565                                 sip->cmd = si->cmd;
16566                                 sip->extra_info = NULL;
16567                                 g_hash_table_insert(si->ct->unmatched, (void *)pid_mid, sip);
16568                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16569                                 new_key->frame = sip->frame_req;
16570                                 new_key->pid_mid = pid_mid;
16571                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16572                         }
16573                 } else {
16574                         /* we have seen this packet before; check the
16575                            matching table.
16576                            If we haven't yet seen the reply, we won't
16577                            find the info for it; we don't need it, as
16578                            we only use it to save information, and, as
16579                            we've seen this packet before, we've already
16580                            saved the information.
16581                         */
16582                         key.frame = pinfo->fd->num;
16583                         key.pid_mid = pid_mid;
16584                         sip=g_hash_table_lookup(si->ct->matched, &key);
16585                 }
16586         }
16587
16588         /*
16589          * Pass the "sip" on to subdissectors through "si".
16590          */
16591         si->sip = sip;
16592
16593         if (sip != NULL) {
16594                 /*
16595                  * Put in fields for the frame number of the frame to which
16596                  * this is a response or the frame with the response to this
16597                  * frame - if we know the frame number (i.e., it's not 0).
16598                  */
16599                 if(si->request){
16600                         if (sip->frame_res != 0)
16601                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
16602                 } else {
16603                         if (sip->frame_req != 0) {
16604                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
16605                                 ns.secs = pinfo->fd->abs_secs - sip->req_time.secs;
16606                                 ns.nsecs = pinfo->fd->abs_usecs*1000 - sip->req_time.nsecs;
16607                                 if(ns.nsecs<0){
16608                                         ns.nsecs+=1000000000;
16609                                         ns.secs--;
16610                                 }
16611                                 proto_tree_add_time(htree, hf_smb_time, tvb,
16612                                     0, 0, &ns);
16613                         }
16614                 }
16615         }
16616
16617         /* smb command */
16618         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);
16619         offset += 1;
16620
16621         if(flags2 & 0x4000){
16622                 /* handle NT 32 bit error code */
16623
16624                 nt_status = tvb_get_letohl(tvb, offset);
16625
16626                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
16627                         TRUE);
16628                 offset += 4;
16629
16630         } else {
16631                 /* handle DOS error code & class */
16632                 errclass = tvb_get_guint8(tvb, offset);
16633                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
16634                         errclass);
16635                 offset += 1;
16636
16637                 /* reserved byte */
16638                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
16639                 offset += 1;
16640
16641                 /* error code */
16642                 /* XXX - the type of this field depends on the value of
16643                  * "errcls", so there is isn't a single value_string array
16644                  * fo it, so there can't be a single field for it.
16645                  */
16646                 errcode = tvb_get_letohs(tvb, offset);
16647                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
16648                         offset, 2, errcode, "Error Code: %s",
16649                         decode_smb_error(errclass, errcode));
16650                 offset += 2;
16651         }
16652
16653         /* flags */
16654         offset = dissect_smb_flags(tvb, htree, offset);
16655
16656         /* flags2 */
16657         offset = dissect_smb_flags2(tvb, htree, offset);
16658
16659         /*
16660          * The document at
16661          *
16662          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
16663          *
16664          * (a text version of "Microsoft Networks SMB FILE SHARING
16665          * PROTOCOL, Document Version 6.0p") says that:
16666          *
16667          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
16668          *      the "High Part of PID";
16669          *
16670          *      the next four bytes are reserved;
16671          *
16672          *      the next four bytes are, for SMB-over-IPX (with no
16673          *      NetBIOS involved) two bytes of Session ID and two bytes
16674          *      of SequenceNumber.
16675          *
16676          * Network Monitor 2.x dissects the four bytes before the Session ID
16677          * as a "Key", and the two bytes after the SequenceNumber as
16678          * a "Group ID".
16679          *
16680          * The "High Part of PID" has been seen in calls other than NT
16681          * Create and X, although most of them appear to be I/O on DCE RPC
16682          * pipes opened with the NT Create and X in question.
16683          */
16684         proto_tree_add_item(htree, hf_smb_pid_high, tvb, offset, 2, TRUE);
16685         offset += 2;
16686
16687         if (pinfo->ptype == PT_IPX &&
16688             (pinfo->match_port == IPX_SOCKET_NWLINK_SMB_SERVER ||
16689              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_REDIR ||
16690              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_MESSENGER)) {
16691                 /*
16692                  * This is SMB-over-IPX.
16693                  * XXX - do we have to worry about "sequenced commands",
16694                  * as per the Samba document?  They say that for
16695                  * "unsequenced commands" (with a sequence number of 0),
16696                  * the Mid must be unique, but perhaps the Mid doesn't
16697                  * have to be unique for sequenced commands.  In at least
16698                  * one capture with SMB-over-IPX, however, the Mids
16699                  * are unique even for sequenced commands.
16700                  */
16701                 /* Key */
16702                 proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
16703                     TRUE);
16704                 offset += 4;
16705
16706                 /* Session ID */
16707                 proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
16708                     TRUE);
16709                 offset += 2;
16710
16711                 /* Sequence number */
16712                 proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
16713                     TRUE);
16714                 offset += 2;
16715
16716                 /* Group ID */
16717                 proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
16718                     TRUE);
16719                 offset += 2;
16720         } else {
16721                 /*
16722                  * According to http://ubiqx.org/cifs/SMB.html#SMB.4.2.1
16723                  * and http://ubiqx.org/cifs/SMB.html#SMB.5.5.1 the 8
16724                  * bytes after the "High part of PID" are an 8-byte
16725                  * signature ...
16726                  */
16727                 proto_tree_add_item(htree, hf_smb_sig, tvb, offset, 8, TRUE);
16728                 offset += 8;
16729
16730                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2, TRUE);
16731                 offset += 2;
16732         }
16733
16734         /* TID */
16735         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si->tid);
16736         offset += 2;
16737
16738         /* PID */
16739         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
16740         offset += 2;
16741
16742         /* UID */
16743         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si->uid);
16744         offset += 2;
16745
16746         /* MID */
16747         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
16748         offset += 2;
16749
16750         pinfo->private_data = si;
16751
16752         /* tap the packet before the dissectors are called so we still get
16753            the tap listener called even if there is an exception.
16754         */
16755         tap_queue_packet(smb_tap, pinfo, si);
16756         dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE);
16757
16758         /* Append error info from this packet to info string. */
16759         if (!si->request && check_col(pinfo->cinfo, COL_INFO)) {
16760                 if (flags2 & 0x4000) {
16761                         /*
16762                          * The status is an NT status code; was there
16763                          * an error?
16764                          */
16765                         if ((nt_status & 0xC0000000) == 0xC0000000) {
16766                                 /*
16767                                  * Yes.
16768                                  */
16769                                 col_append_fstr(
16770                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16771                                         val_to_str(nt_status, NT_errors,
16772                                             "Unknown (0x%08X)"));
16773                         }
16774                 } else {
16775                         /*
16776                          * The status is a DOS error class and code; was
16777                          * there an error?
16778                          */
16779                         if (errclass != SMB_SUCCESS) {
16780                                 /*
16781                                  * Yes.
16782                                  */
16783                                 col_append_fstr(
16784                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16785                                         decode_smb_error(errclass, errcode));
16786                         }
16787                 }
16788         }
16789 }
16790
16791 static gboolean
16792 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16793 {
16794         /* must check that this really is a smb packet */
16795         if (!tvb_bytes_exist(tvb, 0, 4))
16796                 return FALSE;
16797
16798         if( (tvb_get_guint8(tvb, 0) != 0xff)
16799             || (tvb_get_guint8(tvb, 1) != 'S')
16800             || (tvb_get_guint8(tvb, 2) != 'M')
16801             || (tvb_get_guint8(tvb, 3) != 'B') ){
16802                 return FALSE;
16803         }
16804
16805         dissect_smb(tvb, pinfo, parent_tree);
16806         return TRUE;
16807 }
16808
16809 void
16810 proto_register_smb(void)
16811 {
16812         static hf_register_info hf[] = {
16813         { &hf_smb_cmd,
16814                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
16815                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
16816
16817         { &hf_smb_word_count,
16818                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
16819                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
16820
16821         { &hf_smb_byte_count,
16822                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
16823                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
16824
16825         { &hf_smb_response_to,
16826                 { "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
16827                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
16828
16829         { &hf_smb_time,
16830                 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
16831                 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
16832
16833         { &hf_smb_response_in,
16834                 { "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
16835                 NULL, 0, "The response to this packet is in this packet", HFILL }},
16836
16837         { &hf_smb_continuation_to,
16838                 { "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
16839                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
16840
16841         { &hf_smb_nt_status,
16842                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
16843                 VALS(NT_errors), 0, "NT Status code", HFILL }},
16844
16845         { &hf_smb_error_class,
16846                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
16847                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
16848
16849         { &hf_smb_error_code,
16850                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
16851                 NULL, 0, "DOS Error Code", HFILL }},
16852
16853         { &hf_smb_reserved,
16854                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
16855                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
16856
16857         { &hf_smb_sig,
16858                 { "Signature", "smb.signature", FT_BYTES, BASE_HEX,
16859                 NULL, 0, "Signature bytes", HFILL }},
16860
16861         { &hf_smb_key,
16862                 { "Key", "smb.key", FT_UINT32, BASE_HEX,
16863                 NULL, 0, "SMB-over-IPX Key", HFILL }},
16864
16865         { &hf_smb_session_id,
16866                 { "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
16867                 NULL, 0, "SMB-over-IPX Session ID", HFILL }},
16868
16869         { &hf_smb_sequence_num,
16870                 { "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
16871                 NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
16872
16873         { &hf_smb_group_id,
16874                 { "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
16875                 NULL, 0, "SMB-over-IPX Group ID", HFILL }},
16876
16877         { &hf_smb_pid,
16878                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
16879                 NULL, 0, "Process ID", HFILL }},
16880
16881         { &hf_smb_pid_high,
16882                 { "Process ID High", "smb.pid.high", FT_UINT16, BASE_DEC,
16883                 NULL, 0, "Process ID High Bytes", HFILL }},
16884
16885         { &hf_smb_tid,
16886                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
16887                 NULL, 0, "Tree ID", HFILL }},
16888
16889         { &hf_smb_uid,
16890                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
16891                 NULL, 0, "User ID", HFILL }},
16892
16893         { &hf_smb_mid,
16894                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
16895                 NULL, 0, "Multiplex ID", HFILL }},
16896
16897         { &hf_smb_flags_lock,
16898                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
16899                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
16900
16901         { &hf_smb_flags_receive_buffer,
16902                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
16903                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
16904
16905         { &hf_smb_flags_caseless,
16906                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
16907                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
16908
16909         { &hf_smb_flags_canon,
16910                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
16911                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
16912
16913         { &hf_smb_flags_oplock,
16914                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
16915                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
16916
16917         { &hf_smb_flags_notify,
16918                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
16919                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
16920
16921         { &hf_smb_flags_response,
16922                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
16923                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
16924
16925         { &hf_smb_flags2_long_names_allowed,
16926                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
16927                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
16928
16929         { &hf_smb_flags2_ea,
16930                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
16931                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
16932
16933         { &hf_smb_flags2_sec_sig,
16934                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
16935                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
16936
16937         { &hf_smb_flags2_long_names_used,
16938                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
16939                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
16940
16941         { &hf_smb_flags2_esn,
16942                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
16943                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
16944
16945         { &hf_smb_flags2_dfs,
16946                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
16947                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
16948
16949         { &hf_smb_flags2_roe,
16950                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
16951                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
16952
16953         { &hf_smb_flags2_nt_error,
16954                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
16955                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
16956
16957         { &hf_smb_flags2_string,
16958                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
16959                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
16960
16961         { &hf_smb_buffer_format,
16962                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
16963                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
16964
16965         { &hf_smb_dialect_name,
16966                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
16967                 NULL, 0, "Name of dialect", HFILL }},
16968
16969         { &hf_smb_dialect_index,
16970                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
16971                 NULL, 0, "Index of selected dialect", HFILL }},
16972
16973         { &hf_smb_max_trans_buf_size,
16974                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
16975                 NULL, 0, "Maximum transmit buffer size", HFILL }},
16976
16977         { &hf_smb_max_mpx_count,
16978                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
16979                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
16980
16981         { &hf_smb_max_vcs_num,
16982                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
16983                 NULL, 0, "Maximum VCs between client and server", HFILL }},
16984
16985         { &hf_smb_session_key,
16986                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
16987                 NULL, 0, "Unique token identifying this session", HFILL }},
16988
16989         { &hf_smb_server_timezone,
16990                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
16991                 NULL, 0, "Current timezone at server.", HFILL }},
16992
16993         { &hf_smb_encryption_key_length,
16994                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
16995                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
16996
16997         { &hf_smb_encryption_key,
16998                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
16999                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
17000
17001         { &hf_smb_primary_domain,
17002                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
17003                 NULL, 0, "The server's primary domain", HFILL }},
17004
17005         { &hf_smb_server,
17006                 { "Server", "smb.server", FT_STRING, BASE_NONE,
17007                 NULL, 0, "The name of the DC/server", HFILL }},
17008
17009         { &hf_smb_max_raw_buf_size,
17010                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
17011                 NULL, 0, "Maximum raw buffer size", HFILL }},
17012
17013         { &hf_smb_server_guid,
17014                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
17015                 NULL, 0, "Globally unique identifier for this server", HFILL }},
17016
17017         { &hf_smb_security_blob_len,
17018                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
17019                 NULL, 0, "Security blob length", HFILL }},
17020
17021         { &hf_smb_security_blob,
17022                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
17023                 NULL, 0, "Security blob", HFILL }},
17024
17025         { &hf_smb_sm_mode16,
17026                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
17027                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
17028
17029         { &hf_smb_sm_password16,
17030                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
17031                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
17032
17033         { &hf_smb_sm_mode,
17034                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
17035                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
17036
17037         { &hf_smb_sm_password,
17038                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
17039                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
17040
17041         { &hf_smb_sm_signatures,
17042                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
17043                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
17044
17045         { &hf_smb_sm_sig_required,
17046                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
17047                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
17048
17049         { &hf_smb_rm_read,
17050                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
17051                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
17052
17053         { &hf_smb_rm_write,
17054                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
17055                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
17056
17057         { &hf_smb_server_date_time,
17058                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
17059                 NULL, 0, "Current date and time at server", HFILL }},
17060
17061         { &hf_smb_server_smb_date,
17062                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
17063                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
17064
17065         { &hf_smb_server_smb_time,
17066                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
17067                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
17068
17069         { &hf_smb_server_cap_raw_mode,
17070                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
17071                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
17072
17073         { &hf_smb_server_cap_mpx_mode,
17074                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
17075                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
17076
17077         { &hf_smb_server_cap_unicode,
17078                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
17079                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
17080
17081         { &hf_smb_server_cap_large_files,
17082                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
17083                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
17084
17085         { &hf_smb_server_cap_nt_smbs,
17086                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
17087                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
17088
17089         { &hf_smb_server_cap_rpc_remote_apis,
17090                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
17091                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
17092
17093         { &hf_smb_server_cap_nt_status,
17094                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
17095                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
17096
17097         { &hf_smb_server_cap_level_ii_oplocks,
17098                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
17099                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
17100
17101         { &hf_smb_server_cap_lock_and_read,
17102                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
17103                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
17104
17105         { &hf_smb_server_cap_nt_find,
17106                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
17107                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
17108
17109         { &hf_smb_server_cap_dfs,
17110                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
17111                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
17112
17113         { &hf_smb_server_cap_infolevel_passthru,
17114                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
17115                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
17116
17117         { &hf_smb_server_cap_large_readx,
17118                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
17119                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
17120
17121         { &hf_smb_server_cap_large_writex,
17122                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
17123                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
17124
17125         { &hf_smb_server_cap_unix,
17126                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
17127                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
17128
17129         { &hf_smb_server_cap_reserved,
17130                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
17131                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
17132
17133         { &hf_smb_server_cap_bulk_transfer,
17134                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
17135                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
17136
17137         { &hf_smb_server_cap_compressed_data,
17138                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
17139                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
17140
17141         { &hf_smb_server_cap_extended_security,
17142                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
17143                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
17144
17145         { &hf_smb_system_time,
17146                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
17147                 NULL, 0, "System Time", HFILL }},
17148
17149         { &hf_smb_unknown,
17150                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
17151                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
17152
17153         { &hf_smb_dir_name,
17154                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
17155                 NULL, 0, "SMB Directory Name", HFILL }},
17156
17157         { &hf_smb_echo_count,
17158                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
17159                 NULL, 0, "Number of times to echo data back", HFILL }},
17160
17161         { &hf_smb_echo_data,
17162                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
17163                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
17164
17165         { &hf_smb_echo_seq_num,
17166                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
17167                 NULL, 0, "Sequence number for this echo response", HFILL }},
17168
17169         { &hf_smb_max_buf_size,
17170                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
17171                 NULL, 0, "Max client buffer size", HFILL }},
17172
17173         { &hf_smb_path,
17174                 { "Path", "smb.path", FT_STRING, BASE_NONE,
17175                 NULL, 0, "Path. Server name and share name", HFILL }},
17176
17177         { &hf_smb_service,
17178                 { "Service", "smb.service", FT_STRING, BASE_NONE,
17179                 NULL, 0, "Service name", HFILL }},
17180
17181         { &hf_smb_password,
17182                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
17183                 NULL, 0, "Password", HFILL }},
17184
17185         { &hf_smb_ansi_password,
17186                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
17187                 NULL, 0, "ANSI Password", HFILL }},
17188
17189         { &hf_smb_unicode_password,
17190                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
17191                 NULL, 0, "Unicode Password", HFILL }},
17192
17193         { &hf_smb_move_flags_file,
17194                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
17195                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17196
17197         { &hf_smb_move_flags_dir,
17198                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
17199                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17200
17201         { &hf_smb_move_flags_verify,
17202                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
17203                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17204
17205         { &hf_smb_files_moved,
17206                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
17207                 NULL, 0, "Number of files moved", HFILL }},
17208
17209         { &hf_smb_copy_flags_file,
17210                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
17211                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17212
17213         { &hf_smb_copy_flags_dir,
17214                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
17215                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17216
17217         { &hf_smb_copy_flags_dest_mode,
17218                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
17219                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
17220
17221         { &hf_smb_copy_flags_source_mode,
17222                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
17223                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
17224
17225         { &hf_smb_copy_flags_verify,
17226                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
17227                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17228
17229         { &hf_smb_copy_flags_tree_copy,
17230                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
17231                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
17232
17233         { &hf_smb_copy_flags_ea_action,
17234                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
17235                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
17236
17237         { &hf_smb_count,
17238                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
17239                 NULL, 0, "Count number of items/bytes", HFILL }},
17240
17241         { &hf_smb_count_low,
17242                 { "Count Low", "smb.count_low", FT_UINT16, BASE_DEC,
17243                 NULL, 0, "Count number of items/bytes, Low 16 bits", HFILL }},
17244
17245         { &hf_smb_count_high,
17246                 { "Count High (multiply with 64K)", "smb.count_high", FT_UINT16, BASE_DEC,
17247                 NULL, 0, "Count number of items/bytes, High 16 bits", HFILL }},
17248
17249         { &hf_smb_file_name,
17250                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
17251                 NULL, 0, "File Name", HFILL }},
17252
17253         { &hf_smb_open_function_create,
17254                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
17255                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
17256
17257         { &hf_smb_open_function_open,
17258                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
17259                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
17260
17261         { &hf_smb_fid,
17262                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
17263                 NULL, 0, "FID: File ID", HFILL }},
17264
17265         { &hf_smb_file_attr_read_only_16bit,
17266                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
17267                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17268
17269         { &hf_smb_file_attr_read_only_8bit,
17270                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
17271                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17272
17273         { &hf_smb_file_attr_hidden_16bit,
17274                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
17275                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17276
17277         { &hf_smb_file_attr_hidden_8bit,
17278                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
17279                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17280
17281         { &hf_smb_file_attr_system_16bit,
17282                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
17283                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17284
17285         { &hf_smb_file_attr_system_8bit,
17286                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
17287                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17288
17289         { &hf_smb_file_attr_volume_16bit,
17290                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
17291                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
17292
17293         { &hf_smb_file_attr_volume_8bit,
17294                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
17295                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
17296
17297         { &hf_smb_file_attr_directory_16bit,
17298                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
17299                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17300
17301         { &hf_smb_file_attr_directory_8bit,
17302                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
17303                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17304
17305         { &hf_smb_file_attr_archive_16bit,
17306                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
17307                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17308
17309         { &hf_smb_file_attr_archive_8bit,
17310                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
17311                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17312
17313         { &hf_smb_file_attr_device,
17314                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
17315                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
17316
17317         { &hf_smb_file_attr_normal,
17318                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
17319                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
17320
17321         { &hf_smb_file_attr_temporary,
17322                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
17323                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
17324
17325         { &hf_smb_file_attr_sparse,
17326                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
17327                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
17328
17329         { &hf_smb_file_attr_reparse,
17330                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
17331                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
17332
17333         { &hf_smb_file_attr_compressed,
17334                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
17335                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
17336
17337         { &hf_smb_file_attr_offline,
17338                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
17339                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
17340
17341         { &hf_smb_file_attr_not_content_indexed,
17342                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
17343                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
17344
17345         { &hf_smb_file_attr_encrypted,
17346                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
17347                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
17348
17349         { &hf_smb_file_size,
17350                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
17351                 NULL, 0, "File Size", HFILL }},
17352
17353         { &hf_smb_search_attribute_read_only,
17354                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
17355                 TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
17356
17357         { &hf_smb_search_attribute_hidden,
17358                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
17359                 TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
17360
17361         { &hf_smb_search_attribute_system,
17362                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
17363                 TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
17364
17365         { &hf_smb_search_attribute_volume,
17366                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
17367                 TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
17368
17369         { &hf_smb_search_attribute_directory,
17370                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
17371                 TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
17372
17373         { &hf_smb_search_attribute_archive,
17374                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
17375                 TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
17376
17377         { &hf_smb_access_mode,
17378                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
17379                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
17380
17381         { &hf_smb_access_sharing,
17382                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
17383                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
17384
17385         { &hf_smb_access_locality,
17386                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
17387                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
17388
17389         { &hf_smb_access_caching,
17390                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
17391                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
17392
17393         { &hf_smb_access_writetru,
17394                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
17395                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
17396
17397         { &hf_smb_create_time,
17398                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
17399                 NULL, 0, "Creation Time", HFILL }},
17400
17401         { &hf_smb_modify_time,
17402                 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
17403                   NULL, 0, "Modification Time", HFILL }},
17404
17405         { &hf_smb_backup_time,
17406                 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
17407                   NULL, 0, "Backup time", HFILL}},
17408
17409         { &hf_smb_mac_alloc_block_count,
17410                 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
17411                   NULL, 0, "Allocation Block Count", HFILL}},
17412
17413         { &hf_smb_mac_alloc_block_size,
17414                 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
17415                   NULL, 0, "Allocation Block Size", HFILL}},
17416
17417         { &hf_smb_mac_free_block_count,
17418                 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
17419                   NULL, 0, "Free Block Count", HFILL}},
17420
17421         { &hf_smb_mac_root_file_count,
17422                 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
17423                 NULL, 0, "Root File Count", HFILL}},
17424
17425         { &hf_smb_mac_root_dir_count,
17426           { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
17427             NULL, 0, "Root Directory Count", HFILL}},
17428
17429         { &hf_smb_mac_file_count,
17430           { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
17431             NULL, 0, "File Count", HFILL}},
17432
17433         { &hf_smb_mac_dir_count,
17434           { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
17435             NULL, 0, "Directory Count", HFILL}},
17436
17437         { &hf_smb_mac_support_flags,
17438           { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
17439             NULL, 0, "Mac Support Flags", HFILL}},
17440
17441         { &hf_smb_mac_sup_access_ctrl,
17442           { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
17443             TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
17444
17445         { &hf_smb_mac_sup_getset_comments,
17446           { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
17447             TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
17448
17449         { &hf_smb_mac_sup_desktopdb_calls,
17450           { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
17451             TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
17452
17453         { &hf_smb_mac_sup_unique_ids,
17454           { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
17455             TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
17456
17457         { &hf_smb_mac_sup_streams,
17458           { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
17459             TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
17460
17461         { &hf_smb_create_dos_date,
17462                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
17463                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
17464
17465         { &hf_smb_create_dos_time,
17466                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
17467                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
17468
17469         { &hf_smb_last_write_time,
17470                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
17471                 NULL, 0, "Time this file was last written to", HFILL }},
17472
17473         { &hf_smb_last_write_dos_date,
17474                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
17475                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
17476
17477         { &hf_smb_last_write_dos_time,
17478                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
17479                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
17480
17481         { &hf_smb_old_file_name,
17482                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
17483                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
17484
17485         { &hf_smb_offset,
17486                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
17487                 NULL, 0, "Offset in file", HFILL }},
17488
17489         { &hf_smb_remaining,
17490                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
17491                 NULL, 0, "Remaining number of bytes", HFILL }},
17492
17493         { &hf_smb_padding,
17494                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
17495                 NULL, 0, "Padding or unknown data", HFILL }},
17496
17497         { &hf_smb_file_data,
17498                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
17499                 NULL, 0, "Data read/written to the file", HFILL }},
17500
17501         { &hf_smb_mac_fndrinfo,
17502                 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_HEX,
17503                   NULL, 0, "Finder Info", HFILL}},
17504
17505         { &hf_smb_total_data_len,
17506                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
17507                 NULL, 0, "Total length of data", HFILL }},
17508
17509         { &hf_smb_data_len,
17510                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
17511                 NULL, 0, "Length of data", HFILL }},
17512
17513         { &hf_smb_data_len_low,
17514                 { "Data Length Low", "smb.data_len_low", FT_UINT16, BASE_DEC,
17515                 NULL, 0, "Length of data, Low 16 bits", HFILL }},
17516
17517         { &hf_smb_data_len_high,
17518                 { "Data Length High (multiply with 64K)", "smb.data_len_high", FT_UINT16, BASE_DEC,
17519                 NULL, 0, "Length of data, High 16 bits", HFILL }},
17520
17521         { &hf_smb_seek_mode,
17522                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
17523                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
17524
17525         { &hf_smb_access_time,
17526                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
17527                 NULL, 0, "Last Access Time", HFILL }},
17528
17529         { &hf_smb_access_dos_date,
17530                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
17531                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
17532
17533         { &hf_smb_access_dos_time,
17534                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
17535                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
17536
17537         { &hf_smb_data_size,
17538                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
17539                 NULL, 0, "Data Size", HFILL }},
17540
17541         { &hf_smb_alloc_size,
17542                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
17543                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17544
17545         { &hf_smb_max_count,
17546                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
17547                 NULL, 0, "Maximum Count", HFILL }},
17548
17549         { &hf_smb_max_count_low,
17550                 { "Max Count Low", "smb.maxcount_low", FT_UINT16, BASE_DEC,
17551                 NULL, 0, "Maximum Count, Low 16 bits", HFILL }},
17552
17553         { &hf_smb_max_count_high,
17554                 { "Max Count High (multiply with 64K)", "smb.maxcount_high", FT_UINT16, BASE_DEC,
17555                 NULL, 0, "Maximum Count, High 16 bits", HFILL }},
17556
17557         { &hf_smb_min_count,
17558                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
17559                 NULL, 0, "Minimum Count", HFILL }},
17560
17561         { &hf_smb_timeout,
17562                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
17563                 NULL, 0, "Timeout in miliseconds", HFILL }},
17564
17565         { &hf_smb_high_offset,
17566                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
17567                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
17568
17569         { &hf_smb_units,
17570                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
17571                 NULL, 0, "Total number of units at server", HFILL }},
17572
17573         { &hf_smb_bpu,
17574                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
17575                 NULL, 0, "Blocks per unit at server", HFILL }},
17576
17577         { &hf_smb_blocksize,
17578                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
17579                 NULL, 0, "Block size (in bytes) at server", HFILL }},
17580
17581         { &hf_smb_freeunits,
17582                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
17583                 NULL, 0, "Number of free units at server", HFILL }},
17584
17585         { &hf_smb_data_offset,
17586                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17587                 NULL, 0, "Data Offset", HFILL }},
17588
17589         { &hf_smb_dcm,
17590                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
17591                 NULL, 0, "Data Compaction Mode", HFILL }},
17592
17593         { &hf_smb_request_mask,
17594                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
17595                 NULL, 0, "Connectionless mode mask", HFILL }},
17596
17597         { &hf_smb_response_mask,
17598                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
17599                 NULL, 0, "Connectionless mode mask", HFILL }},
17600
17601         { &hf_smb_search_id,
17602                 { "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
17603                 NULL, 0, "Search ID, handle for find operations", HFILL }},
17604
17605         { &hf_smb_write_mode_write_through,
17606                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
17607                 TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
17608
17609         { &hf_smb_write_mode_return_remaining,
17610                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
17611                 TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
17612
17613         { &hf_smb_write_mode_raw,
17614                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
17615                 TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
17616
17617         { &hf_smb_write_mode_message_start,
17618                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
17619                 TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
17620
17621         { &hf_smb_write_mode_connectionless,
17622                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
17623                 TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
17624
17625         { &hf_smb_resume_key_len,
17626                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
17627                 NULL, 0, "Resume Key length", HFILL }},
17628
17629         { &hf_smb_resume_find_id,
17630                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
17631                 NULL, 0, "Handle for Find operation", HFILL }},
17632
17633         { &hf_smb_resume_server_cookie,
17634                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
17635                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
17636
17637         { &hf_smb_resume_client_cookie,
17638                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
17639                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
17640
17641         { &hf_smb_andxoffset,
17642                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
17643                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
17644
17645         { &hf_smb_lock_type_large,
17646                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
17647                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
17648
17649         { &hf_smb_lock_type_cancel,
17650                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
17651                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
17652
17653         { &hf_smb_lock_type_change,
17654                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
17655                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
17656
17657         { &hf_smb_lock_type_oplock,
17658                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
17659                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
17660
17661         { &hf_smb_lock_type_shared,
17662                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
17663                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
17664
17665         { &hf_smb_locking_ol,
17666                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
17667                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
17668
17669         { &hf_smb_number_of_locks,
17670                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
17671                 NULL, 0, "Number of lock requests in this request", HFILL }},
17672
17673         { &hf_smb_number_of_unlocks,
17674                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
17675                 NULL, 0, "Number of unlock requests in this request", HFILL }},
17676
17677         { &hf_smb_lock_long_length,
17678                 { "Length", "smb.lock.length", FT_STRING, BASE_DEC,
17679                 NULL, 0, "Length of lock/unlock region", HFILL }},
17680
17681         { &hf_smb_lock_long_offset,
17682                 { "Offset", "smb.lock.offset", FT_STRING, BASE_DEC,
17683                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
17684
17685         { &hf_smb_file_type,
17686                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
17687                 VALS(filetype_vals), 0, "Type of file", HFILL }},
17688
17689         { &hf_smb_ipc_state_nonblocking,
17690                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
17691                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
17692
17693         { &hf_smb_ipc_state_endpoint,
17694                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
17695                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
17696
17697         { &hf_smb_ipc_state_pipe_type,
17698                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
17699                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
17700
17701         { &hf_smb_ipc_state_read_mode,
17702                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
17703                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
17704
17705         { &hf_smb_ipc_state_icount,
17706                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
17707                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
17708
17709         { &hf_smb_server_fid,
17710                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
17711                 NULL, 0, "Server unique File ID", HFILL }},
17712
17713         { &hf_smb_open_flags_add_info,
17714                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
17715                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
17716
17717         { &hf_smb_open_flags_ex_oplock,
17718                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
17719                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
17720
17721         { &hf_smb_open_flags_batch_oplock,
17722                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
17723                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
17724
17725         { &hf_smb_open_flags_ealen,
17726                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
17727                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
17728
17729         { &hf_smb_open_action_open,
17730                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
17731                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
17732
17733         { &hf_smb_open_action_lock,
17734                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
17735                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
17736
17737         { &hf_smb_vc_num,
17738                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
17739                 NULL, 0, "VC Number", HFILL }},
17740
17741         { &hf_smb_password_len,
17742                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
17743                 NULL, 0, "Length of password", HFILL }},
17744
17745         { &hf_smb_ansi_password_len,
17746                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
17747                 NULL, 0, "Length of ANSI password", HFILL }},
17748
17749         { &hf_smb_unicode_password_len,
17750                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
17751                 NULL, 0, "Length of Unicode password", HFILL }},
17752
17753         { &hf_smb_account,
17754                 { "Account", "smb.account", FT_STRING, BASE_NONE,
17755                 NULL, 0, "Account, username", HFILL }},
17756
17757         { &hf_smb_os,
17758                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
17759                 NULL, 0, "Which OS we are running", HFILL }},
17760
17761         { &hf_smb_lanman,
17762                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
17763                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
17764
17765         { &hf_smb_setup_action_guest,
17766                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
17767                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
17768
17769         { &hf_smb_fs,
17770                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
17771                 NULL, 0, "Native File System", HFILL }},
17772
17773         { &hf_smb_connect_flags_dtid,
17774                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
17775                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
17776
17777         { &hf_smb_connect_support_search,
17778                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
17779                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
17780
17781         { &hf_smb_connect_support_in_dfs,
17782                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
17783                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
17784
17785         { &hf_smb_max_setup_count,
17786                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
17787                 NULL, 0, "Maximum number of setup words to return", HFILL }},
17788
17789         { &hf_smb_total_param_count,
17790                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
17791                 NULL, 0, "Total number of parameter bytes", HFILL }},
17792
17793         { &hf_smb_total_data_count,
17794                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
17795                 NULL, 0, "Total number of data bytes", HFILL }},
17796
17797         { &hf_smb_max_param_count,
17798                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
17799                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
17800
17801         { &hf_smb_max_data_count,
17802                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
17803                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
17804
17805         { &hf_smb_param_disp16,
17806                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
17807                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17808
17809         { &hf_smb_param_count16,
17810                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
17811                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17812
17813         { &hf_smb_param_offset16,
17814                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
17815                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17816
17817         { &hf_smb_param_disp32,
17818                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
17819                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17820
17821         { &hf_smb_param_count32,
17822                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
17823                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17824
17825         { &hf_smb_param_offset32,
17826                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
17827                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17828
17829         { &hf_smb_data_count16,
17830                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
17831                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17832
17833         { &hf_smb_data_disp16,
17834                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
17835                 NULL, 0, "Data Displacement", HFILL }},
17836
17837         { &hf_smb_data_offset16,
17838                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17839                 NULL, 0, "Data Offset", HFILL }},
17840
17841         { &hf_smb_data_count32,
17842                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
17843                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17844
17845         { &hf_smb_data_disp32,
17846                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
17847                 NULL, 0, "Data Displacement", HFILL }},
17848
17849         { &hf_smb_data_offset32,
17850                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
17851                 NULL, 0, "Data Offset", HFILL }},
17852
17853         { &hf_smb_setup_count,
17854                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
17855                 NULL, 0, "Number of setup words in this buffer", HFILL }},
17856
17857         { &hf_smb_nt_trans_subcmd,
17858                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
17859                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
17860
17861         { &hf_smb_nt_ioctl_function_code,
17862                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
17863                 NULL, 0, "NT IOCTL function code", HFILL }},
17864
17865         { &hf_smb_nt_ioctl_isfsctl,
17866                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
17867                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
17868
17869         { &hf_smb_nt_ioctl_flags_root_handle,
17870                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
17871                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
17872
17873         { &hf_smb_nt_ioctl_data,
17874                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
17875                 NULL, 0, "Data for the IOCTL call", HFILL }},
17876
17877         { &hf_smb_nt_notify_action,
17878                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
17879                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
17880
17881         { &hf_smb_nt_notify_watch_tree,
17882                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
17883                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
17884
17885         { &hf_smb_nt_notify_stream_write,
17886                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
17887                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
17888
17889         { &hf_smb_nt_notify_stream_size,
17890                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
17891                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
17892
17893         { &hf_smb_nt_notify_stream_name,
17894                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
17895                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
17896
17897         { &hf_smb_nt_notify_security,
17898                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
17899                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
17900
17901         { &hf_smb_nt_notify_ea,
17902                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
17903                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
17904
17905         { &hf_smb_nt_notify_creation,
17906                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
17907                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
17908
17909         { &hf_smb_nt_notify_last_access,
17910                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
17911                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
17912
17913         { &hf_smb_nt_notify_last_write,
17914                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
17915                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
17916
17917         { &hf_smb_nt_notify_size,
17918                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
17919                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
17920
17921         { &hf_smb_nt_notify_attributes,
17922                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
17923                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
17924
17925         { &hf_smb_nt_notify_dir_name,
17926                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
17927                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
17928
17929         { &hf_smb_nt_notify_file_name,
17930                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
17931                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
17932
17933         { &hf_smb_root_dir_fid,
17934                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
17935                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
17936
17937         { &hf_smb_alloc_size64,
17938                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
17939                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17940
17941         { &hf_smb_nt_create_disposition,
17942                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
17943                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
17944
17945         { &hf_smb_sd_length,
17946                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
17947                 NULL, 0, "Total length of security descriptor", HFILL }},
17948
17949         { &hf_smb_ea_list_length,
17950                 { "EA List Length", "smb.ea.list_length", FT_UINT32, BASE_DEC,
17951                 NULL, 0, "Total length of extended attributes", HFILL }},
17952
17953         { &hf_smb_ea_flags,
17954                 { "EA Flags", "smb.ea.flags", FT_UINT8, BASE_HEX,
17955                 NULL, 0, "EA Flags", HFILL }},
17956
17957         { &hf_smb_ea_name_length,
17958                 { "EA Name Length", "smb.ea.name_length", FT_UINT8, BASE_DEC,
17959                 NULL, 0, "EA Name Length", HFILL }},
17960
17961         { &hf_smb_ea_data_length,
17962                 { "EA Data Length", "smb.ea.data_length", FT_UINT16, BASE_DEC,
17963                 NULL, 0, "EA Data Length", HFILL }},
17964
17965         { &hf_smb_ea_name,
17966                 { "EA Name", "smb.ea.name", FT_STRING, BASE_NONE,
17967                 NULL, 0, "EA Name", HFILL }},
17968
17969         { &hf_smb_ea_data,
17970                 { "EA Data", "smb.ea.data", FT_BYTES, BASE_NONE,
17971                 NULL, 0, "EA Data", HFILL }},
17972
17973         { &hf_smb_file_name_len,
17974                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
17975                 NULL, 0, "Length of File Name", HFILL }},
17976
17977         { &hf_smb_nt_impersonation_level,
17978                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
17979                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
17980
17981         { &hf_smb_nt_security_flags_context_tracking,
17982                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
17983                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
17984
17985         { &hf_smb_nt_security_flags_effective_only,
17986                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
17987                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
17988
17989         { &hf_smb_nt_access_mask_generic_read,
17990                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
17991                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
17992
17993         { &hf_smb_nt_access_mask_generic_write,
17994                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
17995                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
17996
17997         { &hf_smb_nt_access_mask_generic_execute,
17998                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
17999                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
18000
18001         { &hf_smb_nt_access_mask_generic_all,
18002                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
18003                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
18004
18005         { &hf_smb_nt_access_mask_maximum_allowed,
18006                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
18007                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
18008
18009         { &hf_smb_nt_access_mask_system_security,
18010                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
18011                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
18012
18013         { &hf_smb_nt_access_mask_synchronize,
18014                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
18015                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
18016
18017         { &hf_smb_nt_access_mask_write_owner,
18018                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
18019                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
18020
18021         { &hf_smb_nt_access_mask_write_dac,
18022                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
18023                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
18024
18025         { &hf_smb_nt_access_mask_read_control,
18026                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
18027                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
18028
18029         { &hf_smb_nt_access_mask_delete,
18030                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
18031                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
18032
18033         { &hf_smb_nt_access_mask_write_attributes,
18034                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
18035                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
18036
18037         { &hf_smb_nt_access_mask_read_attributes,
18038                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
18039                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
18040
18041         { &hf_smb_nt_access_mask_delete_child,
18042                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
18043                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
18044
18045         /*
18046          * "Execute" for files, "traverse" for directories.
18047          */
18048         { &hf_smb_nt_access_mask_execute,
18049                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
18050                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
18051
18052         { &hf_smb_nt_access_mask_write_ea,
18053                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
18054                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
18055
18056         { &hf_smb_nt_access_mask_read_ea,
18057                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
18058                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
18059
18060         /*
18061          * "Append data" for files, "add subdirectory" for directories,
18062          * "create pipe instance" for named pipes.
18063          */
18064         { &hf_smb_nt_access_mask_append,
18065                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
18066                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
18067
18068         /*
18069          * "Write data" for files and pipes, "add file" for directory.
18070          */
18071         { &hf_smb_nt_access_mask_write,
18072                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
18073                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
18074
18075         /*
18076          * "Read data" for files and pipes, "list directory" for directory.
18077          */
18078         { &hf_smb_nt_access_mask_read,
18079                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
18080                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
18081
18082         { &hf_smb_nt_create_bits_oplock,
18083                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
18084                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
18085
18086         { &hf_smb_nt_create_bits_boplock,
18087                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
18088                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
18089
18090         { &hf_smb_nt_create_bits_dir,
18091                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
18092                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
18093
18094         { &hf_smb_nt_create_bits_ext_resp,
18095           { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32, 
18096             TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
18097
18098         { &hf_smb_nt_create_options_directory_file,
18099                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
18100                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
18101
18102         { &hf_smb_nt_create_options_write_through,
18103                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
18104                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
18105
18106         { &hf_smb_nt_create_options_sequential_only,
18107                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
18108                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
18109
18110         { &hf_smb_nt_create_options_sync_io_alert,
18111                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
18112                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
18113
18114         { &hf_smb_nt_create_options_sync_io_nonalert,
18115                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
18116                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
18117
18118         { &hf_smb_nt_create_options_non_directory_file,
18119                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
18120                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
18121
18122         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
18123            and "NtOpenFile()"; is that sent over the wire?  Network
18124            Monitor thinks so, but its author may just have grabbed
18125            the flag bits from a system header file. */
18126
18127         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
18128            and "NtOpenFile()"; is that sent over the wire?  NetMon
18129            thinks so, but see previous comment. */
18130
18131         { &hf_smb_nt_create_options_no_ea_knowledge,
18132                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
18133                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
18134
18135         { &hf_smb_nt_create_options_eight_dot_three_only,
18136                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
18137                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
18138
18139         { &hf_smb_nt_create_options_random_access,
18140                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
18141                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
18142
18143         { &hf_smb_nt_create_options_delete_on_close,
18144                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
18145                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
18146
18147         /* 0x00002000 is "open by FID", or something such as that (which
18148            I suspect is like "open by inumber" on UNIX), at least in
18149            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
18150            wire?  NetMon thinks so, but see previous comment. */
18151
18152         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
18153            and "NtOpenFile()"; is that sent over the wire?  NetMon
18154            thinks so, but see previous comment. */
18155
18156         { &hf_smb_nt_share_access_read,
18157                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
18158                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
18159
18160         { &hf_smb_nt_share_access_write,
18161                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
18162                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
18163
18164         { &hf_smb_nt_share_access_delete,
18165                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
18166                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
18167
18168         { &hf_smb_file_eattr_read_only,
18169                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
18170                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
18171
18172         { &hf_smb_file_eattr_hidden,
18173                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
18174                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
18175
18176         { &hf_smb_file_eattr_system,
18177                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
18178                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
18179
18180         { &hf_smb_file_eattr_volume,
18181                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
18182                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
18183
18184         { &hf_smb_file_eattr_directory,
18185                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
18186                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
18187
18188         { &hf_smb_file_eattr_archive,
18189                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
18190                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
18191
18192         { &hf_smb_file_eattr_device,
18193                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
18194                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
18195
18196         { &hf_smb_file_eattr_normal,
18197                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
18198                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
18199
18200         { &hf_smb_file_eattr_temporary,
18201                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
18202                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
18203
18204         { &hf_smb_file_eattr_sparse,
18205                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
18206                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
18207
18208         { &hf_smb_file_eattr_reparse,
18209                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
18210                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
18211
18212         { &hf_smb_file_eattr_compressed,
18213                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
18214                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
18215
18216         { &hf_smb_file_eattr_offline,
18217                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
18218                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
18219
18220         { &hf_smb_file_eattr_not_content_indexed,
18221                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
18222                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
18223
18224         { &hf_smb_file_eattr_encrypted,
18225                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
18226                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
18227
18228         { &hf_smb_sec_desc_len,
18229                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
18230                 NULL, 0, "Security Descriptor Length", HFILL }},
18231
18232         { &hf_smb_nt_qsd_owner,
18233                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
18234                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
18235
18236         { &hf_smb_nt_qsd_group,
18237                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
18238                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
18239
18240         { &hf_smb_nt_qsd_dacl,
18241                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
18242                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
18243
18244         { &hf_smb_nt_qsd_sacl,
18245                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
18246                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
18247
18248         { &hf_smb_extended_attributes,
18249                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
18250                 NULL, 0, "Extended Attributes", HFILL }},
18251
18252         { &hf_smb_oplock_level,
18253                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
18254                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
18255
18256         { &hf_smb_create_action,
18257                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
18258                 VALS(oa_open_vals), 0, "Type of action taken", HFILL }},
18259
18260         { &hf_smb_file_id,
18261                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
18262                 NULL, 0, "Server unique file ID", HFILL }},
18263
18264         { &hf_smb_ea_error_offset,
18265                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
18266                 NULL, 0, "Offset into EA list if EA error", HFILL }},
18267
18268         { &hf_smb_end_of_file,
18269                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
18270                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
18271
18272         { &hf_smb_device_type,
18273                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
18274                 VALS(device_type_vals), 0, "Type of device", HFILL }},
18275
18276         { &hf_smb_is_directory,
18277                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
18278                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
18279
18280         { &hf_smb_next_entry_offset,
18281                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
18282                 NULL, 0, "Offset to next entry", HFILL }},
18283
18284         { &hf_smb_change_time,
18285                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
18286                 NULL, 0, "Last Change Time", HFILL }},
18287
18288         { &hf_smb_setup_len,
18289                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
18290                 NULL, 0, "Length of printer setup data", HFILL }},
18291
18292         { &hf_smb_print_mode,
18293                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
18294                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
18295
18296         { &hf_smb_print_identifier,
18297                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
18298                 NULL, 0, "Identifier string for this print job", HFILL }},
18299
18300         { &hf_smb_restart_index,
18301                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
18302                 NULL, 0, "Index of entry after last returned", HFILL }},
18303
18304         { &hf_smb_print_queue_date,
18305                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
18306                 NULL, 0, "Date when this entry was queued", HFILL }},
18307
18308         { &hf_smb_print_queue_dos_date,
18309                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
18310                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
18311
18312         { &hf_smb_print_queue_dos_time,
18313                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
18314                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
18315
18316         { &hf_smb_print_status,
18317                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
18318                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
18319
18320         { &hf_smb_print_spool_file_number,
18321                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
18322                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
18323
18324         { &hf_smb_print_spool_file_size,
18325                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
18326                 NULL, 0, "Number of bytes in spool file", HFILL }},
18327
18328         { &hf_smb_print_spool_file_name,
18329                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
18330                 NULL, 0, "Name of client that submitted this job", HFILL }},
18331
18332         { &hf_smb_start_index,
18333                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
18334                 NULL, 0, "First queue entry to return", HFILL }},
18335
18336         { &hf_smb_originator_name,
18337                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
18338                 NULL, 0, "Name of sender of message", HFILL }},
18339
18340         { &hf_smb_destination_name,
18341                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
18342                 NULL, 0, "Name of recipient of message", HFILL }},
18343
18344         { &hf_smb_message_len,
18345                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
18346                 NULL, 0, "Length of message", HFILL }},
18347
18348         { &hf_smb_message,
18349                 { "Message", "smb.message", FT_STRING, BASE_NONE,
18350                 NULL, 0, "Message text", HFILL }},
18351
18352         { &hf_smb_mgid,
18353                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
18354                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
18355
18356         { &hf_smb_forwarded_name,
18357                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
18358                 NULL, 0, "Recipient name being forwarded", HFILL }},
18359
18360         { &hf_smb_machine_name,
18361                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
18362                 NULL, 0, "Name of target machine", HFILL }},
18363
18364         { &hf_smb_cancel_to,
18365                 { "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
18366                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
18367
18368         { &hf_smb_trans2_subcmd,
18369                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
18370                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
18371
18372         { &hf_smb_trans_name,
18373                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
18374                 NULL, 0, "Name of transaction", HFILL }},
18375
18376         { &hf_smb_transaction_flags_dtid,
18377                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
18378                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
18379
18380         { &hf_smb_transaction_flags_owt,
18381                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
18382                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
18383
18384         { &hf_smb_search_count,
18385                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
18386                 NULL, 0, "Maximum number of search entries to return", HFILL }},
18387
18388         { &hf_smb_search_pattern,
18389                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
18390                 NULL, 0, "Search Pattern", HFILL }},
18391
18392         { &hf_smb_ff2_backup,
18393                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
18394                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
18395
18396         { &hf_smb_ff2_continue,
18397                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
18398                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
18399
18400         { &hf_smb_ff2_resume,
18401                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
18402                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
18403
18404         { &hf_smb_ff2_close_eos,
18405                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
18406                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
18407
18408         { &hf_smb_ff2_close,
18409                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
18410                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
18411
18412         { &hf_smb_ff2_information_level,
18413                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
18414                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
18415
18416         { &hf_smb_qpi_loi,
18417                 { "Level of Interest", "smb.qpi_loi", FT_UINT16, BASE_DEC,
18418                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] QUERY_{FILE,PATH}_INFO commands", HFILL }},
18419
18420         { &hf_smb_spi_loi,
18421                 { "Level of Interest", "smb.spi_loi", FT_UINT16, BASE_DEC,
18422                 VALS(spi_loi_vals), 0, "Level of interest for TRANSACTION[2] SET_{FILE,PATH}_INFO commands", HFILL }},
18423
18424 #if 0
18425         { &hf_smb_sfi_writetru,
18426                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
18427                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
18428
18429         { &hf_smb_sfi_caching,
18430                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
18431                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
18432 #endif
18433
18434         { &hf_smb_storage_type,
18435                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
18436                 NULL, 0, "Type of storage", HFILL }},
18437
18438         { &hf_smb_resume,
18439                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
18440                 NULL, 0, "Resume Key", HFILL }},
18441
18442         { &hf_smb_max_referral_level,
18443                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
18444                 NULL, 0, "Latest referral version number understood", HFILL }},
18445
18446         { &hf_smb_qfsi_information_level,
18447                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_HEX,
18448                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
18449
18450         { &hf_smb_nt_rename_level,
18451                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
18452                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
18453
18454         { &hf_smb_cluster_count,
18455                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
18456                 NULL, 0, "Number of clusters", HFILL }},
18457
18458         { &hf_smb_number_of_links,
18459                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
18460                 NULL, 0, "Number of hard links to the file", HFILL }},
18461
18462         { &hf_smb_delete_pending,
18463                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
18464                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
18465
18466         { &hf_smb_index_number,
18467                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
18468                 NULL, 0, "File system unique identifier", HFILL }},
18469
18470         { &hf_smb_current_offset,
18471                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
18472                 NULL, 0, "Current offset in the file", HFILL }},
18473
18474         { &hf_smb_t2_alignment,
18475                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
18476                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
18477
18478         { &hf_smb_t2_stream_name_length,
18479                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
18480                 NULL, 0, "Length of stream name", HFILL }},
18481
18482         { &hf_smb_t2_stream_size,
18483                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
18484                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18485
18486         { &hf_smb_t2_stream_name,
18487                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
18488                 NULL, 0, "Name of the stream", HFILL }},
18489
18490         { &hf_smb_t2_compressed_file_size,
18491                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
18492                 NULL, 0, "Size of the compressed file", HFILL }},
18493
18494         { &hf_smb_t2_compressed_format,
18495                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
18496                 NULL, 0, "Compression algorithm used", HFILL }},
18497
18498         { &hf_smb_t2_compressed_unit_shift,
18499                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
18500                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18501
18502         { &hf_smb_t2_compressed_chunk_shift,
18503                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
18504                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18505
18506         { &hf_smb_t2_compressed_cluster_shift,
18507                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
18508                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18509
18510         { &hf_smb_t2_marked_for_deletion,
18511                 { "Marked for Deletion", "smb.marked_for_deletion", FT_BOOLEAN, BASE_NONE,
18512                 TFS(&tfs_marked_for_deletion), 0x0, "Marked for deletion?", HFILL }},
18513
18514         { &hf_smb_dfs_path_consumed,
18515                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
18516                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
18517
18518         { &hf_smb_dfs_num_referrals,
18519                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
18520                 NULL, 0, "Number of referrals in this pdu", HFILL }},
18521
18522         { &hf_smb_get_dfs_server_hold_storage,
18523                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
18524                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
18525
18526         { &hf_smb_get_dfs_fielding,
18527                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
18528                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
18529
18530         { &hf_smb_dfs_referral_version,
18531                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
18532                 NULL, 0, "Version of referral element", HFILL }},
18533
18534         { &hf_smb_dfs_referral_size,
18535                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
18536                 NULL, 0, "Size of referral element", HFILL }},
18537
18538         { &hf_smb_dfs_referral_server_type,
18539                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
18540                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
18541
18542         { &hf_smb_dfs_referral_flags_strip,
18543                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
18544                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
18545
18546         { &hf_smb_dfs_referral_node_offset,
18547                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
18548                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
18549
18550         { &hf_smb_dfs_referral_node,
18551                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
18552                 NULL, 0, "Name of entity to visit next", HFILL }},
18553
18554         { &hf_smb_dfs_referral_proximity,
18555                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
18556                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
18557
18558         { &hf_smb_dfs_referral_ttl,
18559                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
18560                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
18561
18562         { &hf_smb_dfs_referral_path_offset,
18563                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
18564                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
18565
18566         { &hf_smb_dfs_referral_path,
18567                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
18568                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
18569
18570         { &hf_smb_dfs_referral_alt_path_offset,
18571                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
18572                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
18573
18574         { &hf_smb_dfs_referral_alt_path,
18575                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
18576                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
18577
18578         { &hf_smb_end_of_search,
18579                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
18580                 NULL, 0, "Was last entry returned?", HFILL }},
18581
18582         { &hf_smb_last_name_offset,
18583                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
18584                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
18585
18586         { &hf_smb_fn_information_level,
18587                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
18588                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
18589
18590         { &hf_smb_monitor_handle,
18591                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
18592                 NULL, 0, "Handle for Find Notify operations", HFILL }},
18593
18594         { &hf_smb_change_count,
18595                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
18596                 NULL, 0, "Number of changes to wait for", HFILL }},
18597
18598         { &hf_smb_file_index,
18599                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
18600                 NULL, 0, "File index", HFILL }},
18601
18602         { &hf_smb_short_file_name,
18603                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
18604                 NULL, 0, "Short (8.3) File Name", HFILL }},
18605
18606         { &hf_smb_short_file_name_len,
18607                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
18608                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
18609
18610         { &hf_smb_fs_id,
18611                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
18612                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
18613
18614         { &hf_smb_fs_guid,
18615                 { "FS GUID", "smb.fs_guid", FT_STRING, BASE_NONE,
18616                 NULL, 0, "File System GUID", HFILL }},
18617
18618         { &hf_smb_sector_unit,
18619                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
18620                 NULL, 0, "Sectors per allocation unit", HFILL }},
18621
18622         { &hf_smb_fs_units,
18623                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
18624                 NULL, 0, "Total number of units on this filesystem", HFILL }},
18625
18626         { &hf_smb_fs_sector,
18627                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
18628                 NULL, 0, "Bytes per sector", HFILL }},
18629
18630         { &hf_smb_avail_units,
18631                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
18632                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
18633
18634         { &hf_smb_volume_serial_num,
18635                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
18636                 NULL, 0, "Volume serial number", HFILL }},
18637
18638         { &hf_smb_volume_label_len,
18639                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
18640                 NULL, 0, "Length of volume label", HFILL }},
18641
18642         { &hf_smb_volume_label,
18643                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
18644                 NULL, 0, "Volume label", HFILL }},
18645
18646         { &hf_smb_free_alloc_units64,
18647                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
18648                 NULL, 0, "Number of free allocation units", HFILL }},
18649
18650         { &hf_smb_caller_free_alloc_units64,
18651                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
18652                 NULL, 0, "Number of caller free allocation units", HFILL }},
18653
18654         { &hf_smb_actual_free_alloc_units64,
18655                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
18656                 NULL, 0, "Number of actual free allocation units", HFILL }},
18657
18658         { &hf_smb_soft_quota_limit,
18659                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
18660                 NULL, 0, "Soft Quota treshold", HFILL }},
18661
18662         { &hf_smb_hard_quota_limit,
18663                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
18664                 NULL, 0, "Hard Quota limit", HFILL }},
18665
18666         { &hf_smb_user_quota_used,
18667                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
18668                 NULL, 0, "How much Quota is used by this user", HFILL }},
18669
18670         { &hf_smb_max_name_len,
18671                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
18672                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
18673
18674         { &hf_smb_fs_name_len,
18675                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
18676                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
18677
18678         { &hf_smb_fs_name,
18679                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
18680                 NULL, 0, "Name of filesystem", HFILL }},
18681
18682         { &hf_smb_device_char_removable,
18683                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
18684                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
18685
18686         { &hf_smb_device_char_read_only,
18687                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
18688                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
18689
18690         { &hf_smb_device_char_floppy,
18691                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
18692                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
18693
18694         { &hf_smb_device_char_write_once,
18695                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
18696                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
18697
18698         { &hf_smb_device_char_remote,
18699                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
18700                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
18701
18702         { &hf_smb_device_char_mounted,
18703                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
18704                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
18705
18706         { &hf_smb_device_char_virtual,
18707                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
18708                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
18709
18710         { &hf_smb_fs_attr_css,
18711                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
18712                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
18713
18714         { &hf_smb_fs_attr_cpn,
18715                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
18716                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
18717
18718         { &hf_smb_fs_attr_pacls,
18719                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
18720                 TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
18721
18722         { &hf_smb_fs_attr_fc,
18723                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
18724                 TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
18725
18726         { &hf_smb_fs_attr_vq,
18727                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
18728                 TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
18729
18730         { &hf_smb_fs_attr_dim,
18731                 { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
18732                 TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
18733
18734         { &hf_smb_fs_attr_vic,
18735                 { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
18736                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
18737
18738         { &hf_smb_sec_desc_revision,
18739                 { "Revision", "smb.sec_desc.revision", FT_UINT8, BASE_DEC,
18740                 NULL, 0, "Version of NT Security Descriptor structure", HFILL }},
18741
18742         { &hf_smb_sid,
18743                 { "SID", "smb.sid", FT_STRING, BASE_DEC,
18744                 NULL, 0, "SID: Security Identifier", HFILL }},
18745
18746         { &hf_smb_sid_revision,
18747                 { "Revision", "smb.sid.revision", FT_UINT8, BASE_DEC,
18748                 NULL, 0, "Version of SID structure", HFILL }},
18749
18750         { &hf_smb_sid_num_auth,
18751                 { "Num Auth", "smb.sid.num_auth", FT_UINT8, BASE_DEC,
18752                 NULL, 0, "Number of authorities for this SID", HFILL }},
18753
18754         { &hf_smb_acl_revision,
18755                 { "Revision", "smb.acl.revision", FT_UINT16, BASE_DEC,
18756                 NULL, 0, "Version of NT ACL structure", HFILL }},
18757
18758         { &hf_smb_acl_size,
18759                 { "Size", "smb.acl.size", FT_UINT16, BASE_DEC,
18760                 NULL, 0, "Size of NT ACL structure", HFILL }},
18761
18762         { &hf_smb_acl_num_aces,
18763                 { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
18764                 NULL, 0, "Number of ACE structures for this ACL", HFILL }},
18765
18766         { &hf_smb_user_quota_offset,
18767                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
18768                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
18769
18770         { &hf_smb_ace_type,
18771                 { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
18772                 VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
18773
18774         { &hf_smb_pipe_write_len,
18775                 { "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
18776                 NULL, 0, "Number of bytes written to pipe", HFILL }},
18777
18778         { &hf_smb_ace_size,
18779                 { "Size", "smb.ace.size", FT_UINT16, BASE_DEC,
18780                 NULL, 0, "Size of this ACE", HFILL }},
18781
18782         { &hf_smb_ace_flags_object_inherit,
18783                 { "Object Inherit", "smb.ace.flags.object_inherit", FT_BOOLEAN, 8,
18784                 TFS(&tfs_ace_flags_object_inherit), 0x01, "Will subordinate files inherit this ACE?", HFILL }},
18785
18786         { &hf_smb_ace_flags_container_inherit,
18787                 { "Container Inherit", "smb.ace.flags.container_inherit", FT_BOOLEAN, 8,
18788                 TFS(&tfs_ace_flags_container_inherit), 0x02, "Will subordinate containers inherit this ACE?", HFILL }},
18789
18790         { &hf_smb_ace_flags_non_propagate_inherit,
18791                 { "Non-Propagate Inherit", "smb.ace.flags.non_propagate_inherit", FT_BOOLEAN, 8,
18792                 TFS(&tfs_ace_flags_non_propagate_inherit), 0x04, "Will subordinate object propagate this ACE further?", HFILL }},
18793
18794         { &hf_smb_ace_flags_inherit_only,
18795                 { "Inherit Only", "smb.ace.flags.inherit_only", FT_BOOLEAN, 8,
18796                 TFS(&tfs_ace_flags_inherit_only), 0x08, "Does this ACE apply to the current object?", HFILL }},
18797
18798         { &hf_smb_ace_flags_inherited_ace,
18799                 { "Inherited ACE", "smb.ace.flags.inherited_ace", FT_BOOLEAN, 8,
18800                 TFS(&tfs_ace_flags_inherited_ace), 0x10, "Was this ACE inherited from its parent object?", HFILL }},
18801
18802         { &hf_smb_ace_flags_successful_access,
18803                 { "Audit Successful Accesses", "smb.ace.flags.successful_access", FT_BOOLEAN, 8,
18804                 TFS(&tfs_ace_flags_successful_access), 0x40, "Should successful accesses be audited?", HFILL }},
18805
18806         { &hf_smb_ace_flags_failed_access,
18807                 { "Audit Failed Accesses", "smb.ace.flags.failed_access", FT_BOOLEAN, 8,
18808                 TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
18809
18810         { &hf_smb_sec_desc_type_owner_defaulted,
18811                 { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
18812                 TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
18813
18814         { &hf_smb_sec_desc_type_group_defaulted,
18815                 { "Group Defaulted", "smb.sec_desc.type.group_defaulted", FT_BOOLEAN, 16,
18816                 TFS(&tfs_sec_desc_type_group_defaulted), 0x0002, "Is Group Defaulted?", HFILL }},
18817
18818         { &hf_smb_sec_desc_type_dacl_present,
18819                 { "DACL Present", "smb.sec_desc.type.dacl_present", FT_BOOLEAN, 16,
18820                 TFS(&tfs_sec_desc_type_dacl_present), 0x0004, "Does this SecDesc have DACL present?", HFILL }},
18821
18822         { &hf_smb_sec_desc_type_dacl_defaulted,
18823                 { "DACL Defaulted", "smb.sec_desc.type.dacl_defaulted", FT_BOOLEAN, 16,
18824                 TFS(&tfs_sec_desc_type_dacl_defaulted), 0x0008, "Does this SecDesc have DACL Defaulted?", HFILL }},
18825
18826         { &hf_smb_sec_desc_type_sacl_present,
18827                 { "SACL Present", "smb.sec_desc.type.sacl_present", FT_BOOLEAN, 16,
18828                 TFS(&tfs_sec_desc_type_sacl_present), 0x0010, "Is the SACL present?", HFILL }},
18829
18830         { &hf_smb_sec_desc_type_sacl_defaulted,
18831                 { "SACL Defaulted", "smb.sec_desc.type.sacl_defaulted", FT_BOOLEAN, 16,
18832                 TFS(&tfs_sec_desc_type_sacl_defaulted), 0x0020, "Does this SecDesc have SACL Defaulted?", HFILL }},
18833
18834         { &hf_smb_sec_desc_type_dacl_auto_inherit_req,
18835                 { "DACL Auto Inherit Required", "smb.sec_desc.type.dacl_auto_inherit_req", FT_BOOLEAN, 16,
18836                 TFS(&tfs_sec_desc_type_dacl_auto_inherit_req), 0x0100, "Does this SecDesc have DACL Auto Inherit Required set?", HFILL }},
18837
18838         { &hf_smb_sec_desc_type_sacl_auto_inherit_req,
18839                 { "SACL Auto Inherit Required", "smb.sec_desc.type.sacl_auto_inherit_req", FT_BOOLEAN, 16,
18840                 TFS(&tfs_sec_desc_type_sacl_auto_inherit_req), 0x0200, "Does this SecDesc have SACL Auto Inherit Required set?", HFILL }},
18841
18842         { &hf_smb_sec_desc_type_dacl_auto_inherited,
18843                 { "DACL Auto Inherited", "smb.sec_desc.type.dacl_auto_inherited", FT_BOOLEAN, 16,
18844                 TFS(&tfs_sec_desc_type_dacl_auto_inherited), 0x0400, "Is this DACL auto inherited", HFILL }},
18845
18846         { &hf_smb_sec_desc_type_sacl_auto_inherited,
18847                 { "SACL Auto Inherited", "smb.sec_desc.type.sacl_auto_inherited", FT_BOOLEAN, 16,
18848                 TFS(&tfs_sec_desc_type_sacl_auto_inherited), 0x0800, "Is this SACL auto inherited", HFILL }},
18849
18850         { &hf_smb_sec_desc_type_dacl_protected,
18851                 { "DACL Protected", "smb.sec_desc.type.dacl_protected", FT_BOOLEAN, 16,
18852                 TFS(&tfs_sec_desc_type_dacl_protected), 0x1000, "Is the DACL structure protected?", HFILL }},
18853
18854         { &hf_smb_sec_desc_type_sacl_protected,
18855                 { "SACL Protected", "smb.sec_desc.type.sacl_protected", FT_BOOLEAN, 16,
18856                 TFS(&tfs_sec_desc_type_sacl_protected), 0x2000, "Is the SACL structure protected?", HFILL }},
18857
18858         { &hf_smb_sec_desc_type_self_relative,
18859                 { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
18860                 TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
18861
18862         { &hf_smb_quota_flags_deny_disk,
18863                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
18864                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
18865
18866         { &hf_smb_quota_flags_log_limit,
18867                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
18868                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
18869
18870         { &hf_smb_quota_flags_log_warning,
18871                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
18872                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
18873
18874         { &hf_smb_quota_flags_enabled,
18875                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
18876                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
18877
18878         { &hf_smb_segment_overlap,
18879                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18880                         "Fragment overlaps with other fragments", HFILL }},
18881
18882         { &hf_smb_segment_overlap_conflict,
18883                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18884                         "Overlapping fragments contained conflicting data", HFILL }},
18885
18886         { &hf_smb_segment_multiple_tails,
18887                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18888                         "Several tails were found when defragmenting the packet", HFILL }},
18889
18890         { &hf_smb_segment_too_long_fragment,
18891                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18892                         "Fragment contained data past end of packet", HFILL }},
18893
18894         { &hf_smb_segment_error,
18895                 { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18896                         "Defragmentation error due to illegal fragments", HFILL }},
18897
18898         { &hf_smb_segment,
18899                 { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18900                         "SMB Segment", HFILL }},
18901
18902         { &hf_smb_segments,
18903                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
18904                         "SMB Segments", HFILL }},
18905
18906         { &hf_smb_unix_major_version,
18907           { "Major Version", "smb.unix.major_version", FT_UINT16, BASE_DEC,
18908             NULL, 0, "UNIX Major Version", HFILL }},
18909
18910         { &hf_smb_unix_minor_version,
18911           { "Minor Version", "smb.unix.minor_version", FT_UINT16, BASE_DEC,
18912             NULL, 0, "UNIX Minor Version", HFILL }},
18913
18914         { &hf_smb_unix_capability_fcntl,
18915           { "FCNTL Capability", "smb.unix.capability.fcntl", FT_BOOLEAN, 32,
18916                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
18917
18918         { &hf_smb_unix_capability_posix_acl,
18919           { "POSIX ACL Capability", "smb.unix.capability.posix_acl", FT_BOOLEAN, 32,
18920                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
18921
18922         { &hf_smb_unix_file_size,
18923           { "File size", "smb.unix.file.size", FT_UINT64, BASE_DEC,
18924             NULL, 0, "", HFILL }},
18925
18926         { &hf_smb_unix_file_num_bytes,
18927           { "Number of bytes", "smb.unix.file.num_bytes", FT_UINT64, BASE_DEC,
18928             NULL, 0, "Number of bytes used to store the file", HFILL }},
18929
18930         { &hf_smb_unix_file_last_status,
18931           { "Last status change", "smb.unix.file.stime", FT_ABSOLUTE_TIME, BASE_NONE,
18932             NULL, 0, "", HFILL }},
18933
18934         { &hf_smb_unix_file_last_access,
18935           { "Last access", "smb.unix.file.atime", FT_ABSOLUTE_TIME, BASE_NONE,
18936             NULL, 0, "", HFILL }},
18937
18938         { &hf_smb_unix_file_last_change,
18939           { "Last modification", "smb.unix.file.mtime", FT_ABSOLUTE_TIME, BASE_NONE,
18940             NULL, 0, "", HFILL }},
18941
18942         { &hf_smb_unix_file_uid,
18943           { "UID", "smb.unix.file.uid", FT_UINT64, BASE_DEC,
18944             NULL, 0, "", HFILL }},
18945
18946         { &hf_smb_unix_file_gid,
18947           { "GID", "smb.unix.file.gid", FT_UINT64, BASE_DEC,
18948             NULL, 0, "", HFILL }},
18949
18950         { &hf_smb_unix_file_type,
18951           { "File type", "smb.unix.file.file_type", FT_UINT32, BASE_DEC,
18952             VALS(unix_file_type_vals), 0, "", HFILL }},
18953
18954         { &hf_smb_unix_file_dev_major,
18955           { "Major device", "smb.unix.file.dev_major", FT_UINT64, BASE_HEX,
18956             NULL, 0, "", HFILL }},
18957
18958         { &hf_smb_unix_file_dev_minor,
18959           { "Minor device", "smb.unix.file.dev_minor", FT_UINT64, BASE_HEX,
18960             NULL, 0, "", HFILL }},
18961
18962         { &hf_smb_unix_file_unique_id,
18963           { "Unique ID", "smb.unix.file.unique_id", FT_UINT64, BASE_HEX,
18964             NULL, 0, "", HFILL }},
18965
18966         { &hf_smb_unix_file_permissions,
18967           { "File permissions", "smb.unix.file.perms", FT_UINT64, BASE_HEX,
18968             NULL, 0, "", HFILL }},
18969
18970         { &hf_smb_unix_file_nlinks,
18971           { "Num links", "smb.unix.file.num_links", FT_UINT64, BASE_DEC,
18972             NULL, 0, "", HFILL }},
18973
18974         { &hf_smb_unix_file_link_dest,
18975           { "Link destination", "smb.unix.file.link_dest", FT_STRING, 
18976             BASE_NONE, NULL, 0, "", HFILL }},
18977
18978         { &hf_smb_unix_find_file_nextoffset,
18979           { "Next entry offset", "smb.unix.find_file.next_offset", FT_UINT32, BASE_DEC,
18980             NULL, 0, "", HFILL }},
18981
18982         { &hf_smb_unix_find_file_resumekey,
18983           { "Resume key", "smb.unix.find_file.resume_key", FT_UINT32, BASE_DEC,
18984             NULL, 0, "", HFILL }},
18985
18986                 /* Access masks */
18987
18988                 { &hf_smb_access_mask,
18989                   { "Access required", "smb.access_mask",
18990                     FT_UINT32, BASE_HEX, NULL, 0x0, "Access mask",
18991                     HFILL }},
18992                 { &hf_access_generic_read,
18993                   { "Generic read", "nt.access_mask.generic_read",
18994                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18995                     GENERIC_READ_ACCESS, "Generic read", HFILL }},
18996
18997                 { &hf_access_generic_write,
18998                   { "Generic write", "nt.access_mask.generic_write",
18999                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19000                     GENERIC_WRITE_ACCESS, "Generic write", HFILL }},
19001
19002                 { &hf_access_generic_execute,
19003                   { "Generic execute", "nt.access_mask.generic_execute",
19004                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19005                     GENERIC_EXECUTE_ACCESS, "Generic execute", HFILL }},
19006
19007                 { &hf_access_generic_all,
19008                   { "Generic all", "nt.access_mask.generic_all",
19009                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19010                     GENERIC_ALL_ACCESS, "Generic all", HFILL }},
19011
19012                 { &hf_access_maximum_allowed,
19013                   { "Maximum allowed", "nt.access_mask.maximum_allowed",
19014                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19015                     MAXIMUM_ALLOWED_ACCESS, "Maximum allowed", HFILL }},
19016
19017                 { &hf_access_sacl,
19018                   { "Access SACL", "nt.access_mask.access_sacl",
19019                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19020                     ACCESS_SACL_ACCESS, "Access SACL", HFILL }},
19021
19022                 { &hf_access_standard_read_control,
19023                   { "Read control", "nt.access_mask.read_control",
19024                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19025                     READ_CONTROL_ACCESS, "Read control", HFILL }},
19026
19027                 { &hf_access_standard_delete,
19028                   { "Delete", "nt.access_mask.delete",
19029                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19030                     DELETE_ACCESS, "Delete", HFILL }},
19031
19032                 { &hf_access_standard_synchronise,
19033                   { "Synchronise", "nt.access_mask.synchronise",
19034                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19035                     SYNCHRONIZE_ACCESS, "Synchronise", HFILL }},
19036
19037                 { &hf_access_standard_write_dac,
19038                   { "Write DAC", "nt.access_mask.write_dac",
19039                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19040                     WRITE_DAC_ACCESS, "Write DAC", HFILL }},
19041
19042                 { &hf_access_standard_write_owner,
19043                   { "Write owner", "nt.access_mask.write_owner",
19044                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19045                     WRITE_OWNER_ACCESS, "Write owner", HFILL }},
19046
19047                 { &hf_access_specific_15,
19048                   { "Specific access, bit 15", "nt.access_mask.specific_15",
19049                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19050                     0x8000, "Specific access, bit 15", HFILL }},
19051
19052                 { &hf_access_specific_14,
19053                   { "Specific access, bit 14", "nt.access_mask.specific_14",
19054                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19055                     0x4000, "Specific access, bit 14", HFILL }},
19056
19057                 { &hf_access_specific_13,
19058                   { "Specific access, bit 13", "nt.access_mask.specific_13",
19059                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19060                     0x2000, "Specific access, bit 13", HFILL }},
19061
19062                 { &hf_access_specific_12,
19063                   { "Specific access, bit 12", "nt.access_mask.specific_12",
19064                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19065                     0x1000, "Specific access, bit 12", HFILL }},
19066
19067                 { &hf_access_specific_11,
19068                   { "Specific access, bit 11", "nt.access_mask.specific_11",
19069                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19070                     0x0800, "Specific access, bit 11", HFILL }},
19071
19072                 { &hf_access_specific_10,
19073                   { "Specific access, bit 10", "nt.access_mask.specific_10",
19074                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19075                     0x0400, "Specific access, bit 10", HFILL }},
19076
19077                 { &hf_access_specific_9,
19078                   { "Specific access, bit 9", "nt.access_mask.specific_9",
19079                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19080                     0x0200, "Specific access, bit 9", HFILL }},
19081
19082                 { &hf_access_specific_8,
19083                   { "Specific access, bit 8", "nt.access_mask.specific_8",
19084                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19085                     0x0100, "Specific access, bit 8", HFILL }},
19086
19087                 { &hf_access_specific_7,
19088                   { "Specific access, bit 7", "nt.access_mask.specific_7",
19089                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19090                     0x0080, "Specific access, bit 7", HFILL }},
19091
19092                 { &hf_access_specific_6,
19093                   { "Specific access, bit 6", "nt.access_mask.specific_6",
19094                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19095                     0x0040, "Specific access, bit 6", HFILL }},
19096
19097                 { &hf_access_specific_5,
19098                   { "Specific access, bit 5", "nt.access_mask.specific_5",
19099                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19100                     0x0020, "Specific access, bit 5", HFILL }},
19101
19102                 { &hf_access_specific_4,
19103                   { "Specific access, bit 4", "nt.access_mask.specific_4",
19104                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19105                     0x0010, "Specific access, bit 4", HFILL }},
19106
19107                 { &hf_access_specific_3,
19108                   { "Specific access, bit 3", "nt.access_mask.specific_3",
19109                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19110                     0x0008, "Specific access, bit 3", HFILL }},
19111
19112                 { &hf_access_specific_2,
19113                   { "Specific access, bit 2", "nt.access_mask.specific_2",
19114                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19115                     0x0004, "Specific access, bit 2", HFILL }},
19116
19117                 { &hf_access_specific_1,
19118                   { "Specific access, bit 1", "nt.access_mask.specific_1",
19119                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19120                     0x0002, "Specific access, bit 1", HFILL }},
19121
19122                 { &hf_access_specific_0,
19123                   { "Specific access, bit 0", "nt.access_mask.specific_0",
19124                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19125                     0x0001, "Specific access, bit 0", HFILL }}
19126         };
19127
19128         static gint *ett[] = {
19129                 &ett_smb,
19130                 &ett_smb_hdr,
19131                 &ett_smb_command,
19132                 &ett_smb_fileattributes,
19133                 &ett_smb_capabilities,
19134                 &ett_smb_aflags,
19135                 &ett_smb_dialect,
19136                 &ett_smb_dialects,
19137                 &ett_smb_mode,
19138                 &ett_smb_rawmode,
19139                 &ett_smb_flags,
19140                 &ett_smb_flags2,
19141                 &ett_smb_desiredaccess,
19142                 &ett_smb_search,
19143                 &ett_smb_file,
19144                 &ett_smb_openfunction,
19145                 &ett_smb_filetype,
19146                 &ett_smb_openaction,
19147                 &ett_smb_writemode,
19148                 &ett_smb_lock_type,
19149                 &ett_smb_ssetupandxaction,
19150                 &ett_smb_optionsup,
19151                 &ett_smb_time_date,
19152                 &ett_smb_move_copy_flags,
19153                 &ett_smb_file_attributes,
19154                 &ett_smb_search_resume_key,
19155                 &ett_smb_search_dir_info,
19156                 &ett_smb_unlocks,
19157                 &ett_smb_unlock,
19158                 &ett_smb_locks,
19159                 &ett_smb_lock,
19160                 &ett_smb_open_flags,
19161                 &ett_smb_ipc_state,
19162                 &ett_smb_open_action,
19163                 &ett_smb_setup_action,
19164                 &ett_smb_connect_flags,
19165                 &ett_smb_connect_support_bits,
19166                 &ett_smb_nt_access_mask,
19167                 &ett_smb_nt_create_bits,
19168                 &ett_smb_nt_create_options,
19169                 &ett_smb_nt_share_access,
19170                 &ett_smb_nt_security_flags,
19171                 &ett_smb_nt_trans_setup,
19172                 &ett_smb_nt_trans_data,
19173                 &ett_smb_nt_trans_param,
19174                 &ett_smb_nt_notify_completion_filter,
19175                 &ett_smb_nt_ioctl_flags,
19176                 &ett_smb_security_information_mask,
19177                 &ett_smb_print_queue_entry,
19178                 &ett_smb_transaction_flags,
19179                 &ett_smb_transaction_params,
19180                 &ett_smb_find_first2_flags,
19181 #if 0
19182                 &ett_smb_ioflag,
19183 #endif
19184                 &ett_smb_transaction_data,
19185                 &ett_smb_stream_info,
19186                 &ett_smb_dfs_referrals,
19187                 &ett_smb_dfs_referral,
19188                 &ett_smb_dfs_referral_flags,
19189                 &ett_smb_get_dfs_flags,
19190                 &ett_smb_ff2_data,
19191                 &ett_smb_device_characteristics,
19192                 &ett_smb_fs_attributes,
19193                 &ett_smb_segments,
19194                 &ett_smb_segment,
19195                 &ett_smb_sec_desc,
19196                 &ett_smb_sid,
19197                 &ett_smb_acl,
19198                 &ett_smb_ace,
19199                 &ett_smb_ace_flags,
19200                 &ett_smb_sec_desc_type,
19201                 &ett_smb_quotaflags,
19202                 &ett_smb_secblob,
19203                 &ett_smb_mac_support_flags,
19204                 &ett_nt_access_mask,
19205                 &ett_nt_access_mask_generic,
19206                 &ett_nt_access_mask_standard,
19207                 &ett_nt_access_mask_specific,
19208                 &ett_smb_unicode_password,
19209                 &ett_smb_ea,
19210                 &ett_smb_unix_capabilities
19211         };
19212         module_t *smb_module;
19213
19214         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
19215             "SMB", "smb");
19216         proto_register_subtree_array(ett, array_length(ett));
19217         proto_register_field_array(proto_smb, hf, array_length(hf));
19218
19219         register_smb_common(proto_smb);
19220
19221         register_init_routine(&smb_init_protocol);
19222         smb_module = prefs_register_protocol(proto_smb, NULL);
19223         prefs_register_bool_preference(smb_module, "trans_reassembly",
19224                 "Reassemble SMB Transaction payload",
19225                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
19226                 &smb_trans_reassembly);
19227         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
19228                 "Reassemble DCERPC over SMB",
19229                 "Whether the dissector should reassemble DCERPC over SMB commands",
19230                 &smb_dcerpc_reassembly);
19231         prefs_register_bool_preference(smb_module, "sid_name_snooping",
19232                 "Snoop SID to Name mappings",
19233                 "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
19234                 &sid_name_snooping);
19235
19236         register_init_routine(smb_trans_reassembly_init);
19237         smb_tap = register_tap("smb");
19238 }
19239
19240 void
19241 proto_reg_handoff_smb(void)
19242 {
19243         dissector_handle_t smb_handle;
19244
19245         gssapi_handle = find_dissector("gssapi");
19246         ntlmssp_handle = find_dissector("ntlmssp");
19247
19248         heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
19249         heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
19250         heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
19251         smb_handle = create_dissector_handle(dissect_smb, proto_smb);
19252         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
19253         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
19254         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER,
19255             smb_handle);
19256 }