The PDU length is 3 bytes long in SLPv2.
[obnox/wireshark/wip.git] / packet-smb.c
1 /* packet-smb.c
2  * Routines for smb packet dissection
3  * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
4  * 2001  Rewrite by Ronnie Sahlberg and Guy Harris
5  *
6  * $Id: packet-smb.c,v 1.372 2003/10/01 08:53:12 guy Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  *
12  * Copied from packet-pop.c
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <stdio.h>
34
35 #include <time.h>
36 #include <string.h>
37 #include <glib.h>
38 #include <ctype.h>
39 #include <epan/int-64bit.h>
40 #include <epan/packet.h>
41 #include <epan/conversation.h>
42 #include "smb.h"
43 #include "alignment.h"
44 #include <epan/strutil.h>
45 #include "prefs.h"
46 #include "reassemble.h"
47 #include "tap.h"
48 #include "packet-ipx.h"
49
50 #include "packet-smb-common.h"
51 #include "packet-smb-mailslot.h"
52 #include "packet-smb-pipe.h"
53 #include "packet-dcerpc.h"
54 #include "packet-smb-sidsnooping.h"
55
56 /*
57  * Various specifications and documents about SMB can be found in
58  *
59  *      ftp://ftp.microsoft.com/developr/drg/CIFS/
60  *
61  * and a CIFS specification from the Storage Networking Industry Association
62  * can be found on a link from the page at
63  *
64  *      http://www.snia.org/tech_activities/CIFS
65  *
66  * (it supercedes the document at
67  *
68  *      ftp://ftp.microsoft.com/developr/drg/CIFS/draft-leach-cifs-v1-spec-01.txt
69  *
70  * ).
71  *
72  * There are also some Open Group publications documenting CIFS available
73  * for download; catalog entries for them are at:
74  *
75  *      http://www.opengroup.org/products/publications/catalog/c209.htm
76  *
77  *      http://www.opengroup.org/products/publications/catalog/c195.htm
78  *
79  * The document "NT LAN Manager SMB File Sharing Protocol Extensions"
80  * can be found at
81  *
82  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
83  *
84  * (or, presumably a similar path under the Samba mirrors).  As the
85  * ".doc" indicates, it's a Word document.  Some of the specs from the
86  * Microsoft FTP site can be found in the
87  *
88  *      http://www.samba.org/samba/ftp/specs/
89  *
90  * directory as well.
91  *
92  * Beware - these specs may have errors.
93  */
94 static int proto_smb = -1;
95 static int hf_smb_cmd = -1;
96 static int hf_smb_key = -1;
97 static int hf_smb_session_id = -1;
98 static int hf_smb_sequence_num = -1;
99 static int hf_smb_group_id = -1;
100 static int hf_smb_pid = -1;
101 static int hf_smb_tid = -1;
102 static int hf_smb_uid = -1;
103 static int hf_smb_mid = -1;
104 static int hf_smb_pid_high = -1;
105 static int hf_smb_sig = -1;
106 static int hf_smb_response_to = -1;
107 static int hf_smb_time = -1;
108 static int hf_smb_response_in = -1;
109 static int hf_smb_continuation_to = -1;
110 static int hf_smb_nt_status = -1;
111 static int hf_smb_error_class = -1;
112 static int hf_smb_error_code = -1;
113 static int hf_smb_reserved = -1;
114 static int hf_smb_flags_lock = -1;
115 static int hf_smb_flags_receive_buffer = -1;
116 static int hf_smb_flags_caseless = -1;
117 static int hf_smb_flags_canon = -1;
118 static int hf_smb_flags_oplock = -1;
119 static int hf_smb_flags_notify = -1;
120 static int hf_smb_flags_response = -1;
121 static int hf_smb_flags2_long_names_allowed = -1;
122 static int hf_smb_flags2_ea = -1;
123 static int hf_smb_flags2_sec_sig = -1;
124 static int hf_smb_flags2_long_names_used = -1;
125 static int hf_smb_flags2_esn = -1;
126 static int hf_smb_flags2_dfs = -1;
127 static int hf_smb_flags2_roe = -1;
128 static int hf_smb_flags2_nt_error = -1;
129 static int hf_smb_flags2_string = -1;
130 static int hf_smb_word_count = -1;
131 static int hf_smb_byte_count = -1;
132 static int hf_smb_buffer_format = -1;
133 static int hf_smb_dialect_name = -1;
134 static int hf_smb_dialect_index = -1;
135 static int hf_smb_max_trans_buf_size = -1;
136 static int hf_smb_max_mpx_count = -1;
137 static int hf_smb_max_vcs_num = -1;
138 static int hf_smb_session_key = -1;
139 static int hf_smb_server_timezone = -1;
140 static int hf_smb_encryption_key_length = -1;
141 static int hf_smb_encryption_key = -1;
142 static int hf_smb_primary_domain = -1;
143 static int hf_smb_server = -1;
144 static int hf_smb_max_raw_buf_size = -1;
145 static int hf_smb_server_guid = -1;
146 static int hf_smb_security_blob_len = -1;
147 static int hf_smb_security_blob = -1;
148 static int hf_smb_sm_mode16 = -1;
149 static int hf_smb_sm_password16 = -1;
150 static int hf_smb_sm_mode = -1;
151 static int hf_smb_sm_password = -1;
152 static int hf_smb_sm_signatures = -1;
153 static int hf_smb_sm_sig_required = -1;
154 static int hf_smb_rm_read = -1;
155 static int hf_smb_rm_write = -1;
156 static int hf_smb_server_date_time = -1;
157 static int hf_smb_server_smb_date = -1;
158 static int hf_smb_server_smb_time = -1;
159 static int hf_smb_server_cap_raw_mode = -1;
160 static int hf_smb_server_cap_mpx_mode = -1;
161 static int hf_smb_server_cap_unicode = -1;
162 static int hf_smb_server_cap_large_files = -1;
163 static int hf_smb_server_cap_nt_smbs = -1;
164 static int hf_smb_server_cap_rpc_remote_apis = -1;
165 static int hf_smb_server_cap_nt_status = -1;
166 static int hf_smb_server_cap_level_ii_oplocks = -1;
167 static int hf_smb_server_cap_lock_and_read = -1;
168 static int hf_smb_server_cap_nt_find = -1;
169 static int hf_smb_server_cap_dfs = -1;
170 static int hf_smb_server_cap_infolevel_passthru = -1;
171 static int hf_smb_server_cap_large_readx = -1;
172 static int hf_smb_server_cap_large_writex = -1;
173 static int hf_smb_server_cap_unix = -1;
174 static int hf_smb_server_cap_reserved = -1;
175 static int hf_smb_server_cap_bulk_transfer = -1;
176 static int hf_smb_server_cap_compressed_data = -1;
177 static int hf_smb_server_cap_extended_security = -1;
178 static int hf_smb_system_time = -1;
179 static int hf_smb_unknown = -1;
180 static int hf_smb_dir_name = -1;
181 static int hf_smb_echo_count = -1;
182 static int hf_smb_echo_data = -1;
183 static int hf_smb_echo_seq_num = -1;
184 static int hf_smb_max_buf_size = -1;
185 static int hf_smb_password = -1;
186 static int hf_smb_password_len = -1;
187 static int hf_smb_ansi_password = -1;
188 static int hf_smb_ansi_password_len = -1;
189 static int hf_smb_unicode_password = -1;
190 static int hf_smb_unicode_password_len = -1;
191 static int hf_smb_path = -1;
192 static int hf_smb_service = -1;
193 static int hf_smb_move_flags_file = -1;
194 static int hf_smb_move_flags_dir = -1;
195 static int hf_smb_move_flags_verify = -1;
196 static int hf_smb_files_moved = -1;
197 static int hf_smb_copy_flags_file = -1;
198 static int hf_smb_copy_flags_dir = -1;
199 static int hf_smb_copy_flags_dest_mode = -1;
200 static int hf_smb_copy_flags_source_mode = -1;
201 static int hf_smb_copy_flags_verify = -1;
202 static int hf_smb_copy_flags_tree_copy = -1;
203 static int hf_smb_copy_flags_ea_action = -1;
204 static int hf_smb_count = -1;
205 static int hf_smb_count_low = -1;
206 static int hf_smb_count_high = -1;
207 static int hf_smb_file_name = -1;
208 static int hf_smb_open_function_open = -1;
209 static int hf_smb_open_function_create = -1;
210 static int hf_smb_fid = -1;
211 static int hf_smb_file_attr_read_only_16bit = -1;
212 static int hf_smb_file_attr_read_only_8bit = -1;
213 static int hf_smb_file_attr_hidden_16bit = -1;
214 static int hf_smb_file_attr_hidden_8bit = -1;
215 static int hf_smb_file_attr_system_16bit = -1;
216 static int hf_smb_file_attr_system_8bit = -1;
217 static int hf_smb_file_attr_volume_16bit = -1;
218 static int hf_smb_file_attr_volume_8bit = -1;
219 static int hf_smb_file_attr_directory_16bit = -1;
220 static int hf_smb_file_attr_directory_8bit = -1;
221 static int hf_smb_file_attr_archive_16bit = -1;
222 static int hf_smb_file_attr_archive_8bit = -1;
223 static int hf_smb_file_attr_device = -1;
224 static int hf_smb_file_attr_normal = -1;
225 static int hf_smb_file_attr_temporary = -1;
226 static int hf_smb_file_attr_sparse = -1;
227 static int hf_smb_file_attr_reparse = -1;
228 static int hf_smb_file_attr_compressed = -1;
229 static int hf_smb_file_attr_offline = -1;
230 static int hf_smb_file_attr_not_content_indexed = -1;
231 static int hf_smb_file_attr_encrypted = -1;
232 static int hf_smb_file_size = -1;
233 static int hf_smb_search_attribute_read_only = -1;
234 static int hf_smb_search_attribute_hidden = -1;
235 static int hf_smb_search_attribute_system = -1;
236 static int hf_smb_search_attribute_volume = -1;
237 static int hf_smb_search_attribute_directory = -1;
238 static int hf_smb_search_attribute_archive = -1;
239 static int hf_smb_access_mode = -1;
240 static int hf_smb_access_sharing = -1;
241 static int hf_smb_access_locality = -1;
242 static int hf_smb_access_caching = -1;
243 static int hf_smb_access_writetru = -1;
244 static int hf_smb_create_time = -1;
245 static int hf_smb_modify_time = -1;
246 static int hf_smb_backup_time = -1;
247 static int hf_smb_mac_alloc_block_count = -1;
248 static int hf_smb_mac_alloc_block_size = -1;
249 static int hf_smb_mac_free_block_count = -1;
250 static int hf_smb_mac_fndrinfo = -1;
251 static int hf_smb_mac_root_file_count = -1;
252 static int hf_smb_mac_root_dir_count = -1;
253 static int hf_smb_mac_file_count = -1;
254 static int hf_smb_mac_dir_count = -1;
255 static int hf_smb_mac_support_flags = -1;
256 static int hf_smb_mac_sup_access_ctrl = -1;
257 static int hf_smb_mac_sup_getset_comments = -1;
258 static int hf_smb_mac_sup_desktopdb_calls = -1;
259 static int hf_smb_mac_sup_unique_ids = -1;
260 static int hf_smb_mac_sup_streams = -1;
261 static int hf_smb_create_dos_date = -1;
262 static int hf_smb_create_dos_time = -1;
263 static int hf_smb_last_write_time = -1;
264 static int hf_smb_last_write_dos_date = -1;
265 static int hf_smb_last_write_dos_time = -1;
266 static int hf_smb_access_time = -1;
267 static int hf_smb_access_dos_date = -1;
268 static int hf_smb_access_dos_time = -1;
269 static int hf_smb_old_file_name = -1;
270 static int hf_smb_offset = -1;
271 static int hf_smb_remaining = -1;
272 static int hf_smb_padding = -1;
273 static int hf_smb_file_data = -1;
274 static int hf_smb_total_data_len = -1;
275 static int hf_smb_data_len = -1;
276 static int hf_smb_data_len_low = -1;
277 static int hf_smb_data_len_high = -1;
278 static int hf_smb_seek_mode = -1;
279 static int hf_smb_data_size = -1;
280 static int hf_smb_alloc_size = -1;
281 static int hf_smb_alloc_size64 = -1;
282 static int hf_smb_max_count = -1;
283 static int hf_smb_max_count_low = -1;
284 static int hf_smb_max_count_high = -1;
285 static int hf_smb_min_count = -1;
286 static int hf_smb_timeout = -1;
287 static int hf_smb_high_offset = -1;
288 static int hf_smb_units = -1;
289 static int hf_smb_bpu = -1;
290 static int hf_smb_blocksize = -1;
291 static int hf_smb_freeunits = -1;
292 static int hf_smb_data_offset = -1;
293 static int hf_smb_dcm = -1;
294 static int hf_smb_request_mask = -1;
295 static int hf_smb_response_mask = -1;
296 static int hf_smb_search_id = -1;
297 static int hf_smb_write_mode_write_through = -1;
298 static int hf_smb_write_mode_return_remaining = -1;
299 static int hf_smb_write_mode_raw = -1;
300 static int hf_smb_write_mode_message_start = -1;
301 static int hf_smb_write_mode_connectionless = -1;
302 static int hf_smb_resume_key_len = -1;
303 static int hf_smb_resume_find_id = -1;
304 static int hf_smb_resume_server_cookie = -1;
305 static int hf_smb_resume_client_cookie = -1;
306 static int hf_smb_andxoffset = -1;
307 static int hf_smb_lock_type_large = -1;
308 static int hf_smb_lock_type_cancel = -1;
309 static int hf_smb_lock_type_change = -1;
310 static int hf_smb_lock_type_oplock = -1;
311 static int hf_smb_lock_type_shared = -1;
312 static int hf_smb_locking_ol = -1;
313 static int hf_smb_number_of_locks = -1;
314 static int hf_smb_number_of_unlocks = -1;
315 static int hf_smb_lock_long_offset = -1;
316 static int hf_smb_lock_long_length = -1;
317 static int hf_smb_file_type = -1;
318 static int hf_smb_ipc_state_nonblocking = -1;
319 static int hf_smb_ipc_state_endpoint = -1;
320 static int hf_smb_ipc_state_pipe_type = -1;
321 static int hf_smb_ipc_state_read_mode = -1;
322 static int hf_smb_ipc_state_icount = -1;
323 static int hf_smb_server_fid = -1;
324 static int hf_smb_open_flags_add_info = -1;
325 static int hf_smb_open_flags_ex_oplock = -1;
326 static int hf_smb_open_flags_batch_oplock = -1;
327 static int hf_smb_open_flags_ealen = -1;
328 static int hf_smb_open_action_open = -1;
329 static int hf_smb_open_action_lock = -1;
330 static int hf_smb_vc_num = -1;
331 static int hf_smb_account = -1;
332 static int hf_smb_os = -1;
333 static int hf_smb_lanman = -1;
334 static int hf_smb_setup_action_guest = -1;
335 static int hf_smb_fs = -1;
336 static int hf_smb_connect_flags_dtid = -1;
337 static int hf_smb_connect_support_search = -1;
338 static int hf_smb_connect_support_in_dfs = -1;
339 static int hf_smb_max_setup_count = -1;
340 static int hf_smb_total_param_count = -1;
341 static int hf_smb_total_data_count = -1;
342 static int hf_smb_max_param_count = -1;
343 static int hf_smb_max_data_count = -1;
344 static int hf_smb_param_disp16 = -1;
345 static int hf_smb_param_count16 = -1;
346 static int hf_smb_param_offset16 = -1;
347 static int hf_smb_param_disp32 = -1;
348 static int hf_smb_param_count32 = -1;
349 static int hf_smb_param_offset32 = -1;
350 static int hf_smb_data_disp16 = -1;
351 static int hf_smb_data_count16 = -1;
352 static int hf_smb_data_offset16 = -1;
353 static int hf_smb_data_disp32 = -1;
354 static int hf_smb_data_count32 = -1;
355 static int hf_smb_data_offset32 = -1;
356 static int hf_smb_setup_count = -1;
357 static int hf_smb_nt_trans_subcmd = -1;
358 static int hf_smb_nt_ioctl_function_code = -1;
359 static int hf_smb_nt_ioctl_isfsctl = -1;
360 static int hf_smb_nt_ioctl_flags_root_handle = -1;
361 static int hf_smb_nt_ioctl_data = -1;
362 #ifdef SMB_UNUSED_HANDLES
363 static int hf_smb_nt_security_information = -1;
364 #endif
365 static int hf_smb_nt_notify_action = -1;
366 static int hf_smb_nt_notify_watch_tree = -1;
367 static int hf_smb_nt_notify_stream_write = -1;
368 static int hf_smb_nt_notify_stream_size = -1;
369 static int hf_smb_nt_notify_stream_name = -1;
370 static int hf_smb_nt_notify_security = -1;
371 static int hf_smb_nt_notify_ea = -1;
372 static int hf_smb_nt_notify_creation = -1;
373 static int hf_smb_nt_notify_last_access = -1;
374 static int hf_smb_nt_notify_last_write = -1;
375 static int hf_smb_nt_notify_size = -1;
376 static int hf_smb_nt_notify_attributes = -1;
377 static int hf_smb_nt_notify_dir_name = -1;
378 static int hf_smb_nt_notify_file_name = -1;
379 static int hf_smb_root_dir_fid = -1;
380 static int hf_smb_nt_create_disposition = -1;
381 static int hf_smb_sd_length = -1;
382 static int hf_smb_ea_list_length = -1;
383 static int hf_smb_ea_flags = -1;
384 static int hf_smb_ea_name_length = -1;
385 static int hf_smb_ea_data_length = -1;
386 static int hf_smb_ea_name = -1;
387 static int hf_smb_ea_data = -1;
388 static int hf_smb_file_name_len = -1;
389 static int hf_smb_nt_impersonation_level = -1;
390 static int hf_smb_nt_security_flags_context_tracking = -1;
391 static int hf_smb_nt_security_flags_effective_only = -1;
392 static int hf_smb_nt_access_mask_generic_read = -1;
393 static int hf_smb_nt_access_mask_generic_write = -1;
394 static int hf_smb_nt_access_mask_generic_execute = -1;
395 static int hf_smb_nt_access_mask_generic_all = -1;
396 static int hf_smb_nt_access_mask_maximum_allowed = -1;
397 static int hf_smb_nt_access_mask_system_security = -1;
398 static int hf_smb_nt_access_mask_synchronize = -1;
399 static int hf_smb_nt_access_mask_write_owner = -1;
400 static int hf_smb_nt_access_mask_write_dac = -1;
401 static int hf_smb_nt_access_mask_read_control = -1;
402 static int hf_smb_nt_access_mask_delete = -1;
403 static int hf_smb_nt_access_mask_write_attributes = -1;
404 static int hf_smb_nt_access_mask_read_attributes = -1;
405 static int hf_smb_nt_access_mask_delete_child = -1;
406 static int hf_smb_nt_access_mask_execute = -1;
407 static int hf_smb_nt_access_mask_write_ea = -1;
408 static int hf_smb_nt_access_mask_read_ea = -1;
409 static int hf_smb_nt_access_mask_append = -1;
410 static int hf_smb_nt_access_mask_write = -1;
411 static int hf_smb_nt_access_mask_read = -1;
412 static int hf_smb_nt_create_bits_oplock = -1;
413 static int hf_smb_nt_create_bits_boplock = -1;
414 static int hf_smb_nt_create_bits_dir = -1;
415 static int hf_smb_nt_create_bits_ext_resp = -1;
416 static int hf_smb_nt_create_options_directory_file = -1;
417 static int hf_smb_nt_create_options_write_through = -1;
418 static int hf_smb_nt_create_options_sequential_only = -1;
419 static int hf_smb_nt_create_options_sync_io_alert = -1;
420 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
421 static int hf_smb_nt_create_options_non_directory_file = -1;
422 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
423 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
424 static int hf_smb_nt_create_options_random_access = -1;
425 static int hf_smb_nt_create_options_delete_on_close = -1;
426 static int hf_smb_nt_share_access_read = -1;
427 static int hf_smb_nt_share_access_write = -1;
428 static int hf_smb_nt_share_access_delete = -1;
429 static int hf_smb_file_eattr_read_only = -1;
430 static int hf_smb_file_eattr_hidden = -1;
431 static int hf_smb_file_eattr_system = -1;
432 static int hf_smb_file_eattr_volume = -1;
433 static int hf_smb_file_eattr_directory = -1;
434 static int hf_smb_file_eattr_archive = -1;
435 static int hf_smb_file_eattr_device = -1;
436 static int hf_smb_file_eattr_normal = -1;
437 static int hf_smb_file_eattr_temporary = -1;
438 static int hf_smb_file_eattr_sparse = -1;
439 static int hf_smb_file_eattr_reparse = -1;
440 static int hf_smb_file_eattr_compressed = -1;
441 static int hf_smb_file_eattr_offline = -1;
442 static int hf_smb_file_eattr_not_content_indexed = -1;
443 static int hf_smb_file_eattr_encrypted = -1;
444 static int hf_smb_sec_desc_len = -1;
445 static int hf_smb_sec_desc_revision = -1;
446 static int hf_smb_sec_desc_type_owner_defaulted = -1;
447 static int hf_smb_sec_desc_type_group_defaulted = -1;
448 static int hf_smb_sec_desc_type_dacl_present = -1;
449 static int hf_smb_sec_desc_type_dacl_defaulted = -1;
450 static int hf_smb_sec_desc_type_sacl_present = -1;
451 static int hf_smb_sec_desc_type_sacl_defaulted = -1;
452 static int hf_smb_sec_desc_type_dacl_auto_inherit_req = -1;
453 static int hf_smb_sec_desc_type_sacl_auto_inherit_req = -1;
454 static int hf_smb_sec_desc_type_dacl_auto_inherited = -1;
455 static int hf_smb_sec_desc_type_sacl_auto_inherited = -1;
456 static int hf_smb_sec_desc_type_dacl_protected = -1;
457 static int hf_smb_sec_desc_type_sacl_protected = -1;
458 static int hf_smb_sec_desc_type_self_relative = -1;
459 static int hf_smb_sid = -1;
460 static int hf_smb_sid_revision = -1;
461 static int hf_smb_sid_num_auth = -1;
462 static int hf_smb_acl_revision = -1;
463 static int hf_smb_acl_size = -1;
464 static int hf_smb_acl_num_aces = -1;
465 static int hf_smb_ace_type = -1;
466 static int hf_smb_ace_size = -1;
467 static int hf_smb_ace_flags_object_inherit = -1;
468 static int hf_smb_ace_flags_container_inherit = -1;
469 static int hf_smb_ace_flags_non_propagate_inherit = -1;
470 static int hf_smb_ace_flags_inherit_only = -1;
471 static int hf_smb_ace_flags_inherited_ace = -1;
472 static int hf_smb_ace_flags_successful_access = -1;
473 static int hf_smb_ace_flags_failed_access = -1;
474 static int hf_smb_nt_qsd_owner = -1;
475 static int hf_smb_nt_qsd_group = -1;
476 static int hf_smb_nt_qsd_dacl = -1;
477 static int hf_smb_nt_qsd_sacl = -1;
478 static int hf_smb_extended_attributes = -1;
479 static int hf_smb_oplock_level = -1;
480 static int hf_smb_create_action = -1;
481 static int hf_smb_file_id = -1;
482 static int hf_smb_ea_error_offset = -1;
483 static int hf_smb_end_of_file = -1;
484 static int hf_smb_device_type = -1;
485 static int hf_smb_is_directory = -1;
486 static int hf_smb_next_entry_offset = -1;
487 static int hf_smb_change_time = -1;
488 static int hf_smb_setup_len = -1;
489 static int hf_smb_print_mode = -1;
490 static int hf_smb_print_identifier = -1;
491 static int hf_smb_restart_index = -1;
492 static int hf_smb_print_queue_date = -1;
493 static int hf_smb_print_queue_dos_date = -1;
494 static int hf_smb_print_queue_dos_time = -1;
495 static int hf_smb_print_status = -1;
496 static int hf_smb_print_spool_file_number = -1;
497 static int hf_smb_print_spool_file_size = -1;
498 static int hf_smb_print_spool_file_name = -1;
499 static int hf_smb_start_index = -1;
500 static int hf_smb_originator_name = -1;
501 static int hf_smb_destination_name = -1;
502 static int hf_smb_message_len = -1;
503 static int hf_smb_message = -1;
504 static int hf_smb_mgid = -1;
505 static int hf_smb_forwarded_name = -1;
506 static int hf_smb_machine_name = -1;
507 static int hf_smb_cancel_to = -1;
508 static int hf_smb_trans2_subcmd = -1;
509 static int hf_smb_trans_name = -1;
510 static int hf_smb_transaction_flags_dtid = -1;
511 static int hf_smb_transaction_flags_owt = -1;
512 static int hf_smb_search_count = -1;
513 static int hf_smb_search_pattern = -1;
514 static int hf_smb_ff2_backup = -1;
515 static int hf_smb_ff2_continue = -1;
516 static int hf_smb_ff2_resume = -1;
517 static int hf_smb_ff2_close_eos = -1;
518 static int hf_smb_ff2_close = -1;
519 static int hf_smb_ff2_information_level = -1;
520 static int hf_smb_qpi_loi = -1;
521 static int hf_smb_spi_loi = -1;
522 #if 0
523 static int hf_smb_sfi_writetru = -1;
524 static int hf_smb_sfi_caching = -1;
525 #endif
526 static int hf_smb_storage_type = -1;
527 static int hf_smb_resume = -1;
528 static int hf_smb_max_referral_level = -1;
529 static int hf_smb_qfsi_information_level = -1;
530 static int hf_smb_number_of_links = -1;
531 static int hf_smb_delete_pending = -1;
532 static int hf_smb_index_number = -1;
533 static int hf_smb_current_offset = -1;
534 static int hf_smb_t2_alignment = -1;
535 static int hf_smb_t2_stream_name_length = -1;
536 static int hf_smb_t2_stream_size = -1;
537 static int hf_smb_t2_stream_name = -1;
538 static int hf_smb_t2_compressed_file_size = -1;
539 static int hf_smb_t2_compressed_format = -1;
540 static int hf_smb_t2_compressed_unit_shift = -1;
541 static int hf_smb_t2_compressed_chunk_shift = -1;
542 static int hf_smb_t2_compressed_cluster_shift = -1;
543 static int hf_smb_t2_marked_for_deletion = -1;
544 static int hf_smb_dfs_path_consumed = -1;
545 static int hf_smb_dfs_num_referrals = -1;
546 static int hf_smb_get_dfs_server_hold_storage = -1;
547 static int hf_smb_get_dfs_fielding = -1;
548 static int hf_smb_dfs_referral_version = -1;
549 static int hf_smb_dfs_referral_size = -1;
550 static int hf_smb_dfs_referral_server_type = -1;
551 static int hf_smb_dfs_referral_flags_strip = -1;
552 static int hf_smb_dfs_referral_node_offset = -1;
553 static int hf_smb_dfs_referral_node = -1;
554 static int hf_smb_dfs_referral_proximity = -1;
555 static int hf_smb_dfs_referral_ttl = -1;
556 static int hf_smb_dfs_referral_path_offset = -1;
557 static int hf_smb_dfs_referral_path = -1;
558 static int hf_smb_dfs_referral_alt_path_offset = -1;
559 static int hf_smb_dfs_referral_alt_path = -1;
560 static int hf_smb_end_of_search = -1;
561 static int hf_smb_last_name_offset = -1;
562 static int hf_smb_fn_information_level = -1;
563 static int hf_smb_monitor_handle = -1;
564 static int hf_smb_change_count = -1;
565 static int hf_smb_file_index = -1;
566 static int hf_smb_short_file_name = -1;
567 static int hf_smb_short_file_name_len = -1;
568 static int hf_smb_fs_id = -1;
569 static int hf_smb_fs_guid = -1;
570 static int hf_smb_sector_unit = -1;
571 static int hf_smb_fs_units = -1;
572 static int hf_smb_fs_sector = -1;
573 static int hf_smb_avail_units = -1;
574 static int hf_smb_volume_serial_num = -1;
575 static int hf_smb_volume_label_len = -1;
576 static int hf_smb_volume_label = -1;
577 static int hf_smb_free_alloc_units64 = -1;
578 static int hf_smb_caller_free_alloc_units64 = -1;
579 static int hf_smb_actual_free_alloc_units64 = -1;
580 static int hf_smb_max_name_len = -1;
581 static int hf_smb_fs_name_len = -1;
582 static int hf_smb_fs_name = -1;
583 static int hf_smb_device_char_removable = -1;
584 static int hf_smb_device_char_read_only = -1;
585 static int hf_smb_device_char_floppy = -1;
586 static int hf_smb_device_char_write_once = -1;
587 static int hf_smb_device_char_remote = -1;
588 static int hf_smb_device_char_mounted = -1;
589 static int hf_smb_device_char_virtual = -1;
590 static int hf_smb_fs_attr_css = -1;
591 static int hf_smb_fs_attr_cpn = -1;
592 static int hf_smb_fs_attr_pacls = -1;
593 static int hf_smb_fs_attr_fc = -1;
594 static int hf_smb_fs_attr_vq = -1;
595 static int hf_smb_fs_attr_dim = -1;
596 static int hf_smb_fs_attr_vic = -1;
597 static int hf_smb_quota_flags_enabled = -1;
598 static int hf_smb_quota_flags_deny_disk = -1;
599 static int hf_smb_quota_flags_log_limit = -1;
600 static int hf_smb_quota_flags_log_warning = -1;
601 static int hf_smb_soft_quota_limit = -1;
602 static int hf_smb_hard_quota_limit = -1;
603 static int hf_smb_user_quota_used = -1;
604 static int hf_smb_user_quota_offset = -1;
605 static int hf_smb_nt_rename_level = -1;
606 static int hf_smb_cluster_count = -1;
607 static int hf_smb_segments = -1;
608 static int hf_smb_segment = -1;
609 static int hf_smb_segment_overlap = -1;
610 static int hf_smb_segment_overlap_conflict = -1;
611 static int hf_smb_segment_multiple_tails = -1;
612 static int hf_smb_segment_too_long_fragment = -1;
613 static int hf_smb_segment_error = -1;
614 static int hf_smb_pipe_write_len = -1;
615 static int hf_smb_unix_major_version = -1;
616 static int hf_smb_unix_minor_version = -1;
617 static int hf_smb_unix_capability_fcntl = -1;
618 static int hf_smb_unix_capability_posix_acl = -1;
619 static int hf_smb_unix_file_size = -1;
620 static int hf_smb_unix_file_num_bytes = -1;
621 static int hf_smb_unix_file_last_status = -1;
622 static int hf_smb_unix_file_last_access = -1;
623 static int hf_smb_unix_file_last_change = -1;
624 static int hf_smb_unix_file_uid = -1;
625 static int hf_smb_unix_file_gid = -1;
626 static int hf_smb_unix_file_type = -1;
627 static int hf_smb_unix_file_dev_major = -1;
628 static int hf_smb_unix_file_dev_minor = -1;
629 static int hf_smb_unix_file_unique_id = -1;
630 static int hf_smb_unix_file_permissions = -1;
631 static int hf_smb_unix_file_nlinks = -1;
632 static int hf_smb_unix_file_link_dest = -1;
633 static int hf_smb_unix_find_file_nextoffset = -1;
634 static int hf_smb_unix_find_file_resumekey = -1;
635
636 static gint ett_smb = -1;
637 static gint ett_smb_hdr = -1;
638 static gint ett_smb_command = -1;
639 static gint ett_smb_fileattributes = -1;
640 static gint ett_smb_capabilities = -1;
641 static gint ett_smb_aflags = -1;
642 static gint ett_smb_dialect = -1;
643 static gint ett_smb_dialects = -1;
644 static gint ett_smb_mode = -1;
645 static gint ett_smb_rawmode = -1;
646 static gint ett_smb_flags = -1;
647 static gint ett_smb_flags2 = -1;
648 static gint ett_smb_desiredaccess = -1;
649 static gint ett_smb_search = -1;
650 static gint ett_smb_file = -1;
651 static gint ett_smb_openfunction = -1;
652 static gint ett_smb_filetype = -1;
653 static gint ett_smb_openaction = -1;
654 static gint ett_smb_writemode = -1;
655 static gint ett_smb_lock_type = -1;
656 static gint ett_smb_ssetupandxaction = -1;
657 static gint ett_smb_optionsup = -1;
658 static gint ett_smb_time_date = -1;
659 static gint ett_smb_move_copy_flags = -1;
660 static gint ett_smb_file_attributes = -1;
661 static gint ett_smb_search_resume_key = -1;
662 static gint ett_smb_search_dir_info = -1;
663 static gint ett_smb_unlocks = -1;
664 static gint ett_smb_unlock = -1;
665 static gint ett_smb_locks = -1;
666 static gint ett_smb_lock = -1;
667 static gint ett_smb_open_flags = -1;
668 static gint ett_smb_ipc_state = -1;
669 static gint ett_smb_open_action = -1;
670 static gint ett_smb_setup_action = -1;
671 static gint ett_smb_connect_flags = -1;
672 static gint ett_smb_connect_support_bits = -1;
673 static gint ett_smb_nt_access_mask = -1;
674 static gint ett_smb_nt_create_bits = -1;
675 static gint ett_smb_nt_create_options = -1;
676 static gint ett_smb_nt_share_access = -1;
677 static gint ett_smb_nt_security_flags = -1;
678 static gint ett_smb_nt_trans_setup = -1;
679 static gint ett_smb_nt_trans_data = -1;
680 static gint ett_smb_nt_trans_param = -1;
681 static gint ett_smb_nt_notify_completion_filter = -1;
682 static gint ett_smb_nt_ioctl_flags = -1;
683 static gint ett_smb_security_information_mask = -1;
684 static gint ett_smb_print_queue_entry = -1;
685 static gint ett_smb_transaction_flags = -1;
686 static gint ett_smb_transaction_params = -1;
687 static gint ett_smb_find_first2_flags = -1;
688 static gint ett_smb_mac_support_flags = -1;
689 #if 0
690 static gint ett_smb_ioflag = -1;
691 #endif
692 static gint ett_smb_transaction_data = -1;
693 static gint ett_smb_stream_info = -1;
694 static gint ett_smb_dfs_referrals = -1;
695 static gint ett_smb_dfs_referral = -1;
696 static gint ett_smb_dfs_referral_flags = -1;
697 static gint ett_smb_get_dfs_flags = -1;
698 static gint ett_smb_ff2_data = -1;
699 static gint ett_smb_device_characteristics = -1;
700 static gint ett_smb_fs_attributes = -1;
701 static gint ett_smb_segments = -1;
702 static gint ett_smb_segment = -1;
703 static gint ett_smb_sec_desc = -1;
704 static gint ett_smb_sid = -1;
705 static gint ett_smb_acl = -1;
706 static gint ett_smb_ace = -1;
707 static gint ett_smb_ace_flags = -1;
708 static gint ett_smb_sec_desc_type = -1;
709 static gint ett_smb_quotaflags = -1;
710 static gint ett_smb_secblob = -1;
711 static gint ett_smb_unicode_password = -1;
712 static gint ett_smb_ea = -1;
713 static gint ett_smb_unix_capabilities = -1;
714
715 static int smb_tap = -1;
716
717 static dissector_handle_t gssapi_handle = NULL;
718 static dissector_handle_t ntlmssp_handle = NULL;
719
720 static const fragment_items smb_frag_items = {
721         &ett_smb_segment,
722         &ett_smb_segments,
723
724         &hf_smb_segments,
725         &hf_smb_segment,
726         &hf_smb_segment_overlap,
727         &hf_smb_segment_overlap_conflict,
728         &hf_smb_segment_multiple_tails,
729         &hf_smb_segment_too_long_fragment,
730         &hf_smb_segment_error,
731         NULL,
732
733         "segments"
734 };
735
736 proto_tree *top_tree=NULL;     /* ugly */
737
738 static char *decode_smb_name(unsigned char);
739 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu);
740
741 /*
742  * Macros for use in the main dissector routines for an SMB.
743  */
744
745 #define WORD_COUNT      \
746         /* Word Count */                                \
747         wc = tvb_get_guint8(tvb, offset);               \
748         proto_tree_add_uint(tree, hf_smb_word_count,    \
749                 tvb, offset, 1, wc);                    \
750         offset += 1;                                    \
751         if(wc==0) goto bytecount;
752
753 #define BYTE_COUNT      \
754         bytecount:                                      \
755         bc = tvb_get_letohs(tvb, offset);               \
756         proto_tree_add_uint(tree, hf_smb_byte_count,    \
757                         tvb, offset, 2, bc);            \
758         offset += 2;                                    \
759         if(bc==0) goto endofcommand;
760
761 #define CHECK_BYTE_COUNT(len)   \
762         if (bc < len) goto endofcommand;
763
764 #define COUNT_BYTES(len)   {\
765         int tmp;            \
766         tmp=len;            \
767         offset += tmp;      \
768         bc -= tmp;          \
769         }
770
771 #define END_OF_SMB      \
772         if (bc != 0) { \
773                 proto_tree_add_text(tree, tvb, offset, bc, \
774                     "Extra byte parameters");           \
775                 offset += bc;                           \
776         }                                               \
777         endofcommand:
778
779 /*
780  * Macros for use in routines called by them.
781  */
782 #define CHECK_BYTE_COUNT_SUBR(len)      \
783         if (*bcp < len) {               \
784                 *trunc = TRUE;          \
785                 return offset;          \
786         }
787
788 #define CHECK_STRING_SUBR(fn)   \
789         if (fn == NULL) {       \
790                 *trunc = TRUE;  \
791                 return offset;  \
792         }
793
794 #define COUNT_BYTES_SUBR(len)   \
795         offset += len;          \
796         *bcp -= len;
797
798 /*
799  * Macros for use when dissecting transaction parameters and data
800  */
801 #define CHECK_BYTE_COUNT_TRANS(len)     \
802         if (bc < len) return offset;
803
804 #define CHECK_STRING_TRANS(fn)  \
805         if (fn == NULL) return offset;
806
807 #define COUNT_BYTES_TRANS(len)  \
808         offset += len;          \
809         bc -= len;
810
811 /*
812  * Macros for use in subrroutines dissecting transaction parameters or data
813  */
814 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
815         if (*bcp < len) return offset;
816
817 #define CHECK_STRING_TRANS_SUBR(fn)     \
818         if (fn == NULL) return offset;
819
820 #define COUNT_BYTES_TRANS_SUBR(len)     \
821         offset += len;                  \
822         *bcp -= len;
823
824
825 gboolean sid_name_snooping = FALSE;
826
827 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
828    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
829    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
830 static gboolean smb_trans_reassembly = FALSE;
831 gboolean smb_dcerpc_reassembly = FALSE;
832
833 static GHashTable *smb_trans_fragment_table = NULL;
834
835 static void
836 smb_trans_reassembly_init(void)
837 {
838         fragment_table_init(&smb_trans_fragment_table);
839 }
840
841 static fragment_data *
842 smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
843                      int offset, int count, int pos, int totlen)
844 {
845         fragment_data *fd_head=NULL;
846         smb_info_t *si;
847         int more_frags;
848
849         more_frags=totlen>(pos+count);
850
851         si = (smb_info_t *)pinfo->private_data;
852         if (si->sip == NULL) {
853                 /*
854                  * We don't have the frame number of the request.
855                  *
856                  * XXX - is there truly nothing we can do here?
857                  * Can we not separately keep track of the original
858                  * transaction and its continuations, as we did
859                  * at one time?
860                  *
861                  * It is probably not much point in even trying to do something here
862                  * if we have never seen the initial request. Without the initial
863                  * request we probably miss all parameters and the begining of data
864                  * so we cant even call a subdissector since we can not determine
865                  * which type of transaction call this is.
866                  */
867                 return NULL;
868         }
869
870         if(!pinfo->fd->flags.visited){
871                 fd_head = fragment_add(tvb, offset, pinfo,
872                                        si->sip->frame_req, smb_trans_fragment_table,
873                                        pos, count, more_frags);
874         } else {
875                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
876         }
877
878         /* we only show the defragmented packet for the first fragment,
879            or else we might end up with dissecting one HUGE transaction PDU
880            a LOT of times. (first fragment is the only one containing the setup
881            bytes)
882            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction
883            SMBs. Takes a LOT of time dissecting and is not fun.
884         */
885         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
886                 return fd_head;
887         } else {
888                 return NULL;
889         }
890 }
891
892
893
894
895
896 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
897    These variables and functions are used to match
898    responses with calls
899    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
900 /*
901  * The information we need to save about a request in order to show the
902  * frame number of the request in the dissection of the reply.
903  */
904 typedef struct  {
905         guint32 frame;
906         guint32 pid_mid;
907 } smb_saved_info_key_t;
908
909 static GMemChunk *smb_saved_info_key_chunk = NULL;
910 static GMemChunk *smb_saved_info_chunk = NULL;
911 static int smb_saved_info_init_count = 200;
912
913 /* unmatched smb_saved_info structures.
914    For unmatched smb_saved_info structures we store the smb_saved_info
915    structure using the MID and the PID as the key.
916
917    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
918    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
919    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
920 */
921 static gint
922 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
923 {
924         register guint32 key1 = (guint32)k1;
925         register guint32 key2 = (guint32)k2;
926         return key1==key2;
927 }
928 static guint
929 smb_saved_info_hash_unmatched(gconstpointer k)
930 {
931         register guint32 key = (guint32)k;
932         return key;
933 }
934
935 /* matched smb_saved_info structures.
936    For matched smb_saved_info structures we store the smb_saved_info
937    structure twice in the table using the frame number, and a combination
938    of the MID and the PID, as the key.
939    The frame number is guaranteed to be unique but if ever someone makes
940    some change that will renumber the frames in a capture we are in BIG trouble.
941    This is not likely though since that would break (among other things) all the
942    reassembly routines as well.
943
944    We also need the MID as there may be more than one SMB request or reply
945    in a single frame, and we also need the PID as there may be more than
946    one outstanding request with the same MID and different PIDs.
947 */
948 static gint
949 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
950 {
951         const smb_saved_info_key_t *key1 = k1;
952         const smb_saved_info_key_t *key2 = k2;
953         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
954 }
955 static guint
956 smb_saved_info_hash_matched(gconstpointer k)
957 {
958         const smb_saved_info_key_t *key = k;
959         return key->frame + key->pid_mid;
960 }
961
962 static GMemChunk *smb_nt_transact_info_chunk = NULL;
963 static int smb_nt_transact_info_init_count = 200;
964
965 static GMemChunk *smb_transact2_info_chunk = NULL;
966 static int smb_transact2_info_init_count = 200;
967
968 /*
969  * The information we need to save about a Transaction request in order
970  * to dissect the reply; this includes information for use by the
971  * Remote API dissector.
972  */
973 static GMemChunk *smb_transact_info_chunk = NULL;
974 static int smb_transact_info_init_count = 200;
975
976 static GMemChunk *conv_tables_chunk = NULL;
977 static GSList *conv_tables = NULL;
978 static int conv_tables_count = 10;
979
980
981 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
982    End of request/response matching functions
983    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
984
985 static const value_string buffer_format_vals[] = {
986         {1,     "Data Block"},
987         {2,     "Dialect"},
988         {3,     "Pathname"},
989         {4,     "ASCII"},
990         {5,     "Variable Block"},
991         {0,     NULL}
992 };
993
994 /*
995  * UTIME - this is *almost* like a UNIX time stamp, except that it's
996  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
997  * January 1, 1970, 00:00:00 GMT.
998  *
999  * This means we have to do some extra work to convert it.  This code is
1000  * based on the Samba code:
1001  *
1002  *      Unix SMB/Netbios implementation.
1003  *      Version 1.9.
1004  *      time handling functions
1005  *      Copyright (C) Andrew Tridgell 1992-1998
1006  */
1007
1008 /*
1009  * Yield the difference between *A and *B, in seconds, ignoring leap
1010  * seconds.
1011  */
1012 #define TM_YEAR_BASE 1900
1013
1014 static int
1015 tm_diff(struct tm *a, struct tm *b)
1016 {
1017         int ay = a->tm_year + (TM_YEAR_BASE - 1);
1018         int by = b->tm_year + (TM_YEAR_BASE - 1);
1019         int intervening_leap_days =
1020             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
1021         int years = ay - by;
1022         int days =
1023             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
1024         int hours = 24*days + (a->tm_hour - b->tm_hour);
1025         int minutes = 60*hours + (a->tm_min - b->tm_min);
1026         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
1027
1028         return seconds;
1029 }
1030
1031 /*
1032  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
1033  * determined.
1034  */
1035 static int
1036 TimeZone(time_t t)
1037 {
1038         struct tm *tm = gmtime(&t);
1039         struct tm tm_utc;
1040
1041         if (tm == NULL)
1042                 return 0;
1043         tm_utc = *tm;
1044         tm = localtime(&t);
1045         if (tm == NULL)
1046                 return 0;
1047         return tm_diff(&tm_utc,tm);
1048 }
1049
1050 /*
1051  * Return the same value as TimeZone, but it should be more efficient.
1052  *
1053  * We keep a table of DST offsets to prevent calling localtime() on each
1054  * call of this function. This saves a LOT of time on many unixes.
1055  *
1056  * Updated by Paul Eggert <eggert@twinsun.com>
1057  */
1058 #ifndef CHAR_BIT
1059 #define CHAR_BIT 8
1060 #endif
1061
1062 #ifndef TIME_T_MIN
1063 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1064                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
1065 #endif
1066 #ifndef TIME_T_MAX
1067 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
1068 #endif
1069
1070 static int
1071 TimeZoneFaster(time_t t)
1072 {
1073         static struct dst_table {time_t start,end; int zone;} *tdt;
1074         static struct dst_table *dst_table = NULL;
1075         static int table_size = 0;
1076         int i;
1077         int zone = 0;
1078
1079         if (t == 0)
1080                 t = time(NULL);
1081
1082         /* Tunis has a 8 day DST region, we need to be careful ... */
1083 #define MAX_DST_WIDTH (365*24*60*60)
1084 #define MAX_DST_SKIP (7*24*60*60)
1085
1086         for (i = 0; i < table_size; i++) {
1087                 if (t >= dst_table[i].start && t <= dst_table[i].end)
1088                         break;
1089         }
1090
1091         if (i < table_size) {
1092                 zone = dst_table[i].zone;
1093         } else {
1094                 time_t low,high;
1095
1096                 zone = TimeZone(t);
1097                 if (dst_table == NULL)
1098                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1099                 else
1100                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1101                 if (tdt == NULL) {
1102                         if (dst_table)
1103                                 g_free(dst_table);
1104                         table_size = 0;
1105                 } else {
1106                         dst_table = tdt;
1107                         table_size++;
1108
1109                         dst_table[i].zone = zone;
1110                         dst_table[i].start = dst_table[i].end = t;
1111
1112                         /* no entry will cover more than 6 months */
1113                         low = t - MAX_DST_WIDTH/2;
1114                         if (t < low)
1115                                 low = TIME_T_MIN;
1116
1117                         high = t + MAX_DST_WIDTH/2;
1118                         if (high < t)
1119                                 high = TIME_T_MAX;
1120
1121                         /*
1122                          * Widen the new entry using two bisection searches.
1123                          */
1124                         while (low+60*60 < dst_table[i].start) {
1125                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1126                                         t = dst_table[i].start - MAX_DST_SKIP;
1127                                 else
1128                                         t = low + (dst_table[i].start-low)/2;
1129                                 if (TimeZone(t) == zone)
1130                                         dst_table[i].start = t;
1131                                 else
1132                                         low = t;
1133                         }
1134
1135                         while (high-60*60 > dst_table[i].end) {
1136                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1137                                         t = dst_table[i].end + MAX_DST_SKIP;
1138                                 else
1139                                         t = high - (high-dst_table[i].end)/2;
1140                                 if (TimeZone(t) == zone)
1141                                         dst_table[i].end = t;
1142                                 else
1143                                         high = t;
1144                         }
1145                 }
1146         }
1147         return zone;
1148 }
1149
1150 /*
1151  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1152  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1153  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1154  * daylight savings transitions because some local times are ambiguous.
1155  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1156  */
1157 static int
1158 LocTimeDiff(time_t lt)
1159 {
1160         int d = TimeZoneFaster(lt);
1161         time_t t = lt + d;
1162
1163         /* if overflow occurred, ignore all the adjustments so far */
1164         if (((t < lt) ^ (d < 0)))
1165                 t = lt;
1166
1167         /*
1168          * Now t should be close enough to the true UTC to yield the
1169          * right answer.
1170          */
1171         return TimeZoneFaster(t);
1172 }
1173
1174 static int
1175 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1176 {
1177         guint32 timeval;
1178         nstime_t ts;
1179
1180         timeval = tvb_get_letohl(tvb, offset);
1181         if (timeval == 0xffffffff) {
1182                 proto_tree_add_text(tree, tvb, offset, 4,
1183                     "%s: No time specified (0xffffffff)",
1184                     proto_registrar_get_name(hf_date));
1185                 offset += 4;
1186                 return offset;
1187         }
1188
1189         /*
1190          * We add the local time offset.
1191          */
1192         ts.secs = timeval + LocTimeDiff(timeval);
1193         ts.nsecs = 0;
1194
1195         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1196         offset += 4;
1197
1198         return offset;
1199 }
1200
1201 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
1202
1203 /*
1204  * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits,
1205  * to an "nstime_t".
1206  * A FILETIME is a 64-bit integer, giving the time since Jan 1, 1601,
1207  * midnight "UTC", in 100ns units.
1208  * Return TRUE if the conversion succeeds, FALSE otherwise.
1209  *
1210  * According to the Samba code, it appears to be kludge-GMT (at least for
1211  * file listings). This means it's the GMT you get by taking a local time
1212  * and adding the server time zone offset.  This is NOT the same as GMT in
1213  * some cases.   However, we don't know the server time zone, so we don't
1214  * do that adjustment.
1215  *
1216  * This code is based on the Samba code:
1217  *
1218  *      Unix SMB/Netbios implementation.
1219  *      Version 1.9.
1220  *      time handling functions
1221  *      Copyright (C) Andrew Tridgell 1992-1998
1222  */
1223 static gboolean
1224 nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
1225 {
1226         double d;
1227         /* The next two lines are a fix needed for the
1228             broken SCO compiler. JRA. */
1229         time_t l_time_min = TIME_T_MIN;
1230         time_t l_time_max = TIME_T_MAX;
1231
1232         if (filetime_high == 0)
1233                 return FALSE;
1234
1235         /*
1236          * Get the time as a double, in seconds and fractional seconds.
1237          */
1238         d = ((double)filetime_high)*4.0*(double)(1<<30);
1239         d += filetime_low;
1240         d *= 1.0e-7;
1241
1242         /* Now adjust by 369 years, to make the seconds since 1970. */
1243         d -= TIME_FIXUP_CONSTANT;
1244
1245         if (!(l_time_min <= d && d <= l_time_max))
1246                 return FALSE;
1247
1248         /*
1249          * Get the time as seconds and nanoseconds.
1250          */
1251         tv->secs = d;
1252         tv->nsecs = (d - tv->secs)*1000000000;
1253
1254         return TRUE;
1255 }
1256
1257 int
1258 dissect_smb_64bit_time(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1259 {
1260         guint32 filetime_high, filetime_low;
1261         nstime_t ts;
1262
1263         /* XXX there seems also to be another special time value which is fairly common :
1264            0x40000000 00000000
1265            the meaning of this one is yet unknown
1266         */
1267         if (tree) {
1268                 filetime_low = tvb_get_letohl(tvb, offset);
1269                 filetime_high = tvb_get_letohl(tvb, offset + 4);
1270                 if (filetime_low == 0 && filetime_high == 0) {
1271                         proto_tree_add_text(tree, tvb, offset, 8,
1272                             "%s: No time specified (0)",
1273                             proto_registrar_get_name(hf_date));
1274                 } else if(filetime_low==0 && filetime_high==0x80000000){
1275                         proto_tree_add_text(tree, tvb, offset, 8,
1276                             "%s: Infinity (relative time)",
1277                             proto_registrar_get_name(hf_date));
1278                 } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
1279                         proto_tree_add_text(tree, tvb, offset, 8,
1280                             "%s: Infinity (absolute time)",
1281                             proto_registrar_get_name(hf_date));
1282                 } else {
1283                         if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
1284                                 proto_tree_add_time(tree, hf_date, tvb,
1285                                     offset, 8, &ts);
1286                         } else {
1287                                 proto_tree_add_text(tree, tvb, offset, 8,
1288                                     "%s: Time can't be converted",
1289                                     proto_registrar_get_name(hf_date));
1290                         }
1291                 }
1292         }
1293
1294         offset += 8;
1295         return offset;
1296 }
1297
1298 static int
1299 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1300     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1301 {
1302         guint16 dos_time, dos_date;
1303         proto_item *item = NULL;
1304         proto_tree *tree = NULL;
1305         struct tm tm;
1306         time_t t;
1307         static const int mday_noleap[12] = {
1308                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1309         };
1310         static const int mday_leap[12] = {
1311                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1312         };
1313 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1314         nstime_t tv;
1315
1316         if (time_first) {
1317                 dos_time = tvb_get_letohs(tvb, offset);
1318                 dos_date = tvb_get_letohs(tvb, offset+2);
1319         } else {
1320                 dos_date = tvb_get_letohs(tvb, offset);
1321                 dos_time = tvb_get_letohs(tvb, offset+2);
1322         }
1323
1324         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1325             (dos_date == 0 && dos_time == 0)) {
1326                 /*
1327                  * No date/time specified.
1328                  */
1329                 if(parent_tree){
1330                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1331                             "%s: No time specified (0x%08x)",
1332                             proto_registrar_get_name(hf_date),
1333                             (dos_date << 16) | dos_time);
1334                 }
1335                 offset += 4;
1336                 return offset;
1337         }
1338
1339         tm.tm_sec = (dos_time&0x1f)*2;
1340         tm.tm_min = (dos_time>>5)&0x3f;
1341         tm.tm_hour = (dos_time>>11)&0x1f;
1342         tm.tm_mday = dos_date&0x1f;
1343         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1344         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1345         tm.tm_isdst = -1;
1346
1347         /*
1348          * Do some sanity checks before calling "mktime()";
1349          * "mktime()" doesn't do them, it "normalizes" out-of-range
1350          * values.
1351          */
1352         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1353            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1354            (ISLEAP(tm.tm_year + 1900) ?
1355              tm.tm_mday > mday_leap[tm.tm_mon] :
1356              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1357              (t = mktime(&tm)) == -1) {
1358                 /*
1359                  * Invalid date/time.
1360                  */
1361                 if (parent_tree) {
1362                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1363                             "%s: Invalid time",
1364                             proto_registrar_get_name(hf_date));
1365                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1366                         if (time_first) {
1367                                 proto_tree_add_uint_format(tree, hf_dos_time, tvb, offset, 2, dos_time, "DOS Time: %02d:%02d:%02d (0x%04x)", tm.tm_hour, tm.tm_min, tm.tm_sec, dos_time);
1368                                 proto_tree_add_uint_format(tree, hf_dos_date, tvb, offset+2, 2, dos_date, "DOS Date: %04d-%02d-%02d (0x%04x)", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, dos_date);
1369                         } else {
1370                                 proto_tree_add_uint_format(tree, hf_dos_date, tvb, offset, 2, dos_date, "DOS Date: %04d-%02d-%02d (0x%04x)", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, dos_date);
1371                                 proto_tree_add_uint_format(tree, hf_dos_time, tvb, offset+2, 2, dos_time, "DOS Time: %02d:%02d:%02d (0x%04x)", tm.tm_hour, tm.tm_min, tm.tm_sec, dos_time);
1372                         }
1373                 }
1374                 offset += 4;
1375                 return offset;
1376         }
1377
1378         tv.secs = t;
1379         tv.nsecs = 0;
1380
1381         if(parent_tree){
1382                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1383                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1384                 if (time_first) {
1385                         proto_tree_add_uint_format(tree, hf_dos_time, tvb, offset, 2, dos_time, "DOS Time: %02d:%02d:%02d (0x%04x)", tm.tm_hour, tm.tm_min, tm.tm_sec, dos_time);
1386                         proto_tree_add_uint_format(tree, hf_dos_date, tvb, offset+2, 2, dos_date, "DOS Date: %04d-%02d-%02d (0x%04x)", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, dos_date);
1387                 } else {
1388                         proto_tree_add_uint_format(tree, hf_dos_date, tvb, offset, 2, dos_date, "DOS Date: %04d-%02d-%02d (0x%04x)", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, dos_date);
1389                         proto_tree_add_uint_format(tree, hf_dos_time, tvb, offset+2, 2, dos_time, "DOS Time: %02d:%02d:%02d (0x%04x)", tm.tm_hour, tm.tm_min, tm.tm_sec, dos_time);
1390                 }
1391         }
1392
1393         offset += 4;
1394
1395         return offset;
1396 }
1397
1398
1399 static const value_string da_access_vals[] = {
1400         { 0,            "Open for reading"},
1401         { 1,            "Open for writing"},
1402         { 2,            "Open for reading and writing"},
1403         { 3,            "Open for execute"},
1404         {0, NULL}
1405 };
1406 static const value_string da_sharing_vals[] = {
1407         { 0,            "Compatibility mode"},
1408         { 1,            "Deny read/write/execute (exclusive)"},
1409         { 2,            "Deny write"},
1410         { 3,            "Deny read/execute"},
1411         { 4,            "Deny none"},
1412         {0, NULL}
1413 };
1414 static const value_string da_locality_vals[] = {
1415         { 0,            "Locality of reference unknown"},
1416         { 1,            "Mainly sequential access"},
1417         { 2,            "Mainly random access"},
1418         { 3,            "Random access with some locality"},
1419         {0, NULL}
1420 };
1421 static const true_false_string tfs_da_caching = {
1422         "Do not cache this file",
1423         "Caching permitted on this file"
1424 };
1425 static const true_false_string tfs_da_writetru = {
1426         "Write through enabled",
1427         "Write through disabled"
1428 };
1429 static int
1430 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, char *type)
1431 {
1432         guint16 mask;
1433         proto_item *item = NULL;
1434         proto_tree *tree = NULL;
1435
1436         mask = tvb_get_letohs(tvb, offset);
1437
1438         if(parent_tree){
1439                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1440                         "%s Access: 0x%04x", type, mask);
1441                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1442         }
1443
1444         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1445                 tvb, offset, 2, mask);
1446         proto_tree_add_boolean(tree, hf_smb_access_caching,
1447                 tvb, offset, 2, mask);
1448         proto_tree_add_uint(tree, hf_smb_access_locality,
1449                 tvb, offset, 2, mask);
1450         proto_tree_add_uint(tree, hf_smb_access_sharing,
1451                 tvb, offset, 2, mask);
1452         proto_tree_add_uint(tree, hf_smb_access_mode,
1453                 tvb, offset, 2, mask);
1454
1455         offset += 2;
1456
1457         return offset;
1458 }
1459
1460 #define SMB_FILE_ATTRIBUTE_READ_ONLY            0x00000001
1461 #define SMB_FILE_ATTRIBUTE_HIDDEN               0x00000002
1462 #define SMB_FILE_ATTRIBUTE_SYSTEM               0x00000004
1463 #define SMB_FILE_ATTRIBUTE_VOLUME               0x00000008
1464 #define SMB_FILE_ATTRIBUTE_DIRECTORY            0x00000010
1465 #define SMB_FILE_ATTRIBUTE_ARCHIVE              0x00000020
1466 #define SMB_FILE_ATTRIBUTE_DEVICE               0x00000040
1467 #define SMB_FILE_ATTRIBUTE_NORMAL               0x00000080
1468 #define SMB_FILE_ATTRIBUTE_TEMPORARY            0x00000100
1469 #define SMB_FILE_ATTRIBUTE_SPARSE               0x00000200
1470 #define SMB_FILE_ATTRIBUTE_REPARSE              0x00000400
1471 #define SMB_FILE_ATTRIBUTE_COMPRESSED           0x00000800
1472 #define SMB_FILE_ATTRIBUTE_OFFLINE              0x00001000
1473 #define SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
1474 #define SMB_FILE_ATTRIBUTE_ENCRYPTED            0x00004000
1475
1476 static const true_false_string tfs_file_attribute_read_only = {
1477         "This file is READ ONLY",
1478         "This file is NOT read only",
1479 };
1480 static const true_false_string tfs_file_attribute_hidden = {
1481         "This is a HIDDEN file",
1482         "This is NOT a hidden file"
1483 };
1484 static const true_false_string tfs_file_attribute_system = {
1485         "This is a SYSTEM file",
1486         "This is NOT a system file"
1487 };
1488 static const true_false_string tfs_file_attribute_volume = {
1489         "This is a VOLUME ID",
1490         "This is NOT a volume ID"
1491 };
1492 static const true_false_string tfs_file_attribute_directory = {
1493         "This is a DIRECTORY",
1494         "This is NOT a directory"
1495 };
1496 static const true_false_string tfs_file_attribute_archive = {
1497         "This file has been modified since last ARCHIVE",
1498         "This file has NOT been modified since last archive"
1499 };
1500 static const true_false_string tfs_file_attribute_device = {
1501         "This is a DEVICE",
1502         "This is NOT a device"
1503 };
1504 static const true_false_string tfs_file_attribute_normal = {
1505         "This file is an ordinary file",
1506         "This file has some attribute set"
1507 };
1508 static const true_false_string tfs_file_attribute_temporary = {
1509         "This is a TEMPORARY file",
1510         "This is NOT a temporary file"
1511 };
1512 static const true_false_string tfs_file_attribute_sparse = {
1513         "This is a SPARSE file",
1514         "This is NOT a sparse file"
1515 };
1516 static const true_false_string tfs_file_attribute_reparse = {
1517         "This file has an associated REPARSE POINT",
1518         "This file does NOT have an associated reparse point"
1519 };
1520 static const true_false_string tfs_file_attribute_compressed = {
1521         "This is a COMPRESSED file",
1522         "This is NOT a compressed file"
1523 };
1524 static const true_false_string tfs_file_attribute_offline = {
1525         "This file is OFFLINE",
1526         "This file is NOT offline"
1527 };
1528 static const true_false_string tfs_file_attribute_not_content_indexed = {
1529         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1530         "This file MAY be indexed by the content indexing service"
1531 };
1532 static const true_false_string tfs_file_attribute_encrypted = {
1533         "This is an ENCRYPTED file",
1534         "This is NOT an encrypted file"
1535 };
1536
1537 /*
1538  * In some places in the CIFS_TR_1p00.pdf, from SNIA, file attributes are 
1539  * listed as USHORT, and seem to be in packets in the wild, while in other
1540  * places they are listed as ULONG, and also seem to be.
1541  *
1542  * So, I (Richard Sharpe), added a parameter to allow us to specify how many
1543  * bytes to consume.
1544  */
1545
1546 static int
1547 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1548                         int bytes)
1549 {
1550         guint16 mask;
1551         proto_item *item = NULL;
1552         proto_tree *tree = NULL;
1553
1554         if (bytes != 2 && bytes != 4) {
1555
1556                 fprintf(stderr, "Incorrect number of bytes passed to dissect_file_attributes.\nMust be 2 or 4, was %d\n", bytes);
1557                 exit(1);
1558
1559         }
1560
1561         /*
1562          * The actual bits of interest appear to only be a USHORT
1563          */
1564         /* FIXME if this ever changes! */
1565         mask = tvb_get_letohs(tvb, offset);
1566
1567         if(parent_tree){
1568                 item = proto_tree_add_text(parent_tree, tvb, offset, bytes,
1569                         "File Attributes: 0x%08x", mask);
1570                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1571         }
1572         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted, 
1573                                tvb, offset, bytes, mask);       
1574         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed, 
1575                                tvb, offset, bytes, mask);
1576         proto_tree_add_boolean(tree, hf_smb_file_attr_offline, 
1577                                tvb, offset, bytes, mask);
1578         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed, 
1579                                tvb, offset, bytes, mask);
1580         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse, 
1581                                tvb, offset, bytes, mask);
1582         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse, 
1583                                tvb, offset, bytes, mask);
1584         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary, 
1585                                tvb, offset, bytes, mask);
1586         proto_tree_add_boolean(tree, hf_smb_file_attr_normal, 
1587                                tvb, offset, bytes, mask);
1588         proto_tree_add_boolean(tree, hf_smb_file_attr_device, 
1589                                tvb, offset, bytes, mask);
1590         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1591                 tvb, offset, bytes, mask);
1592         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1593                 tvb, offset, bytes, mask);
1594         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1595                 tvb, offset, bytes, mask);
1596         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1597                 tvb, offset, bytes, mask);
1598         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1599                 tvb, offset, bytes, mask);
1600         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1601                 tvb, offset, bytes, mask);
1602
1603         offset += bytes;
1604
1605         return offset;
1606 }
1607
1608 /* 3.11 */
1609 static int
1610 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1611 {
1612         guint32 mask;
1613         proto_item *item = NULL;
1614         proto_tree *tree = NULL;
1615
1616         mask = tvb_get_letohl(tvb, offset);
1617
1618         if(parent_tree){
1619                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1620                         "File Attributes: 0x%08x", mask);
1621                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1622         }
1623
1624         /*
1625          * XXX - Network Monitor disagrees on some of the
1626          * bits, e.g. the bits above temporary are "atomic write"
1627          * and "transaction write", and it says nothing about the
1628          * bits above that.
1629          *
1630          * Does the Win32 API documentation, or the NT Native API book,
1631          * suggest anything?
1632          */
1633         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1634                 tvb, offset, 4, mask);
1635         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1636                 tvb, offset, 4, mask);
1637         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1638                 tvb, offset, 4, mask);
1639         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1640                 tvb, offset, 4, mask);
1641         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1642                 tvb, offset, 4, mask);
1643         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1644                 tvb, offset, 4, mask);
1645         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1646                 tvb, offset, 4, mask);
1647         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1648                 tvb, offset, 4, mask);
1649         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1650                 tvb, offset, 4, mask);
1651         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1652                 tvb, offset, 4, mask);
1653         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1654                 tvb, offset, 4, mask);
1655         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1656                 tvb, offset, 4, mask);
1657         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1658                 tvb, offset, 4, mask);
1659         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1660                 tvb, offset, 4, mask);
1661         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1662                 tvb, offset, 4, mask);
1663
1664         offset += 4;
1665
1666         return offset;
1667 }
1668
1669 static int
1670 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1671 {
1672         guint8 mask;
1673         proto_item *item = NULL;
1674         proto_tree *tree = NULL;
1675
1676         mask = tvb_get_guint8(tvb, offset);
1677
1678         if(parent_tree){
1679                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1680                         "File Attributes: 0x%02x", mask);
1681                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1682         }
1683         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1684                 tvb, offset, 1, mask);
1685         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1686                 tvb, offset, 1, mask);
1687         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1688                 tvb, offset, 1, mask);
1689         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1690                 tvb, offset, 1, mask);
1691         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1692                 tvb, offset, 1, mask);
1693         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1694                 tvb, offset, 1, mask);
1695
1696         offset += 1;
1697
1698         return offset;
1699 }
1700
1701 static const true_false_string tfs_search_attribute_read_only = {
1702         "Include READ ONLY files in search results",
1703         "Do NOT include read only files in search results",
1704 };
1705 static const true_false_string tfs_search_attribute_hidden = {
1706         "Include HIDDEN files in search results",
1707         "Do NOT include hidden files in search results"
1708 };
1709 static const true_false_string tfs_search_attribute_system = {
1710         "Include SYSTEM files in search results",
1711         "Do NOT include system files in search results"
1712 };
1713 static const true_false_string tfs_search_attribute_volume = {
1714         "Include VOLUME IDs in search results",
1715         "Do NOT include volume IDs in search results"
1716 };
1717 static const true_false_string tfs_search_attribute_directory = {
1718         "Include DIRECTORIES in search results",
1719         "Do NOT include directories in search results"
1720 };
1721 static const true_false_string tfs_search_attribute_archive = {
1722         "Include ARCHIVE files in search results",
1723         "Do NOT include archive files in search results"
1724 };
1725
1726 static int
1727 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1728 {
1729         guint16 mask;
1730         proto_item *item = NULL;
1731         proto_tree *tree = NULL;
1732
1733         mask = tvb_get_letohs(tvb, offset);
1734
1735         if(parent_tree){
1736                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1737                         "Search Attributes: 0x%04x", mask);
1738                 tree = proto_item_add_subtree(item, ett_smb_search);
1739         }
1740
1741         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1742                 tvb, offset, 2, mask);
1743         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1744                 tvb, offset, 2, mask);
1745         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1746                 tvb, offset, 2, mask);
1747         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1748                 tvb, offset, 2, mask);
1749         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1750                 tvb, offset, 2, mask);
1751         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1752                 tvb, offset, 2, mask);
1753
1754         offset += 2;
1755         return offset;
1756 }
1757
1758 #if 0
1759 /*
1760  * XXX - this isn't used.
1761  * Is this used for anything?  NT Create AndX doesn't use it.
1762  * Is there some 16-bit attribute field with more bits than Read Only,
1763  * Hidden, System, Volume ID, Directory, and Archive?
1764  */
1765 static int
1766 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1767 {
1768         guint32 mask;
1769         proto_item *item = NULL;
1770         proto_tree *tree = NULL;
1771
1772         mask = tvb_get_letohl(tvb, offset);
1773
1774         if(parent_tree){
1775                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1776                         "File Attributes: 0x%08x", mask);
1777                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1778         }
1779         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1780                 tvb, offset, 2, mask);
1781         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1782                 tvb, offset, 2, mask);
1783         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1784                 tvb, offset, 2, mask);
1785         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1786                 tvb, offset, 2, mask);
1787         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1788                 tvb, offset, 2, mask);
1789         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1790                 tvb, offset, 2, mask);
1791         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1792                 tvb, offset, 2, mask);
1793         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1794                 tvb, offset, 2, mask);
1795         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1796                 tvb, offset, 2, mask);
1797         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1798                 tvb, offset, 2, mask);
1799         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1800                 tvb, offset, 2, mask);
1801         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1802                 tvb, offset, 2, mask);
1803         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1804                 tvb, offset, 2, mask);
1805         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1806                 tvb, offset, 2, mask);
1807         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1808                 tvb, offset, 2, mask);
1809
1810         offset += 2;
1811
1812         return offset;
1813 }
1814 #endif
1815
1816
1817 #define SERVER_CAP_RAW_MODE            0x00000001
1818 #define SERVER_CAP_MPX_MODE            0x00000002
1819 #define SERVER_CAP_UNICODE             0x00000004
1820 #define SERVER_CAP_LARGE_FILES         0x00000008
1821 #define SERVER_CAP_NT_SMBS             0x00000010
1822 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1823 #define SERVER_CAP_STATUS32            0x00000040
1824 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1825 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1826 #define SERVER_CAP_NT_FIND             0x00000200
1827 #define SERVER_CAP_DFS                 0x00001000
1828 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1829 #define SERVER_CAP_LARGE_READX         0x00004000
1830 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1831 #define SERVER_CAP_UNIX                0x00800000
1832 #define SERVER_CAP_RESERVED            0x02000000
1833 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1834 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1835 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1836 static const true_false_string tfs_server_cap_raw_mode = {
1837         "Read Raw and Write Raw are supported",
1838         "Read Raw and Write Raw are not supported"
1839 };
1840 static const true_false_string tfs_server_cap_mpx_mode = {
1841         "Read Mpx and Write Mpx are supported",
1842         "Read Mpx and Write Mpx are not supported"
1843 };
1844 static const true_false_string tfs_server_cap_unicode = {
1845         "Unicode strings are supported",
1846         "Unicode strings are not supported"
1847 };
1848 static const true_false_string tfs_server_cap_large_files = {
1849         "Large files are supported",
1850         "Large files are not supported",
1851 };
1852 static const true_false_string tfs_server_cap_nt_smbs = {
1853         "NT SMBs are supported",
1854         "NT SMBs are not supported"
1855 };
1856 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1857         "RPC remote APIs are supported",
1858         "RPC remote APIs are not supported"
1859 };
1860 static const true_false_string tfs_server_cap_nt_status = {
1861         "NT status codes are supported",
1862         "NT status codes are not supported"
1863 };
1864 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1865         "Level 2 oplocks are supported",
1866         "Level 2 oplocks are not supported"
1867 };
1868 static const true_false_string tfs_server_cap_lock_and_read = {
1869         "Lock and Read is supported",
1870         "Lock and Read is not supported"
1871 };
1872 static const true_false_string tfs_server_cap_nt_find = {
1873         "NT Find is supported",
1874         "NT Find is not supported"
1875 };
1876 static const true_false_string tfs_server_cap_dfs = {
1877         "Dfs is supported",
1878         "Dfs is not supported"
1879 };
1880 static const true_false_string tfs_server_cap_infolevel_passthru = {
1881         "NT information level request passthrough is supported",
1882         "NT information level request passthrough is not supported"
1883 };
1884 static const true_false_string tfs_server_cap_large_readx = {
1885         "Large Read andX is supported",
1886         "Large Read andX is not supported"
1887 };
1888 static const true_false_string tfs_server_cap_large_writex = {
1889         "Large Write andX is supported",
1890         "Large Write andX is not supported"
1891 };
1892 static const true_false_string tfs_server_cap_unix = {
1893         "UNIX extensions are supported",
1894         "UNIX extensions are not supported"
1895 };
1896 static const true_false_string tfs_server_cap_reserved = {
1897         "Reserved",
1898         "Reserved"
1899 };
1900 static const true_false_string tfs_server_cap_bulk_transfer = {
1901         "Bulk Read and Bulk Write are supported",
1902         "Bulk Read and Bulk Write are not supported"
1903 };
1904 static const true_false_string tfs_server_cap_compressed_data = {
1905         "Compressed data transfer is supported",
1906         "Compressed data transfer is not supported"
1907 };
1908 static const true_false_string tfs_server_cap_extended_security = {
1909         "Extended security exchanges are supported",
1910         "Extended security exchanges are not supported"
1911 };
1912 static int
1913 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1914 {
1915         guint32 mask;
1916         proto_item *item = NULL;
1917         proto_tree *tree = NULL;
1918
1919         mask = tvb_get_letohl(tvb, offset);
1920
1921         if(parent_tree){
1922                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1923                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1924         }
1925
1926         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1927                 tvb, offset, 4, mask);
1928         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1929                 tvb, offset, 4, mask);
1930         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1931                 tvb, offset, 4, mask);
1932         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1933                 tvb, offset, 4, mask);
1934         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1935                 tvb, offset, 4, mask);
1936         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1937                 tvb, offset, 4, mask);
1938         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1939                 tvb, offset, 4, mask);
1940         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1941                 tvb, offset, 4, mask);
1942         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1943                 tvb, offset, 4, mask);
1944         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1945                 tvb, offset, 4, mask);
1946         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1947                 tvb, offset, 4, mask);
1948         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1949                 tvb, offset, 4, mask);
1950         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1951                 tvb, offset, 4, mask);
1952         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1953                 tvb, offset, 4, mask);
1954         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1955                 tvb, offset, 4, mask);
1956         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1957                 tvb, offset, 4, mask);
1958         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1959                 tvb, offset, 4, mask);
1960         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1961                 tvb, offset, 4, mask);
1962         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1963                 tvb, offset, 4, mask);
1964
1965         return mask;
1966 }
1967
1968 #define RAWMODE_READ   0x01
1969 #define RAWMODE_WRITE  0x02
1970 static const true_false_string tfs_rm_read = {
1971         "Read Raw is supported",
1972         "Read Raw is not supported"
1973 };
1974 static const true_false_string tfs_rm_write = {
1975         "Write Raw is supported",
1976         "Write Raw is not supported"
1977 };
1978
1979 static int
1980 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1981 {
1982         guint16 mask;
1983         proto_item *item = NULL;
1984         proto_tree *tree = NULL;
1985
1986         mask = tvb_get_letohs(tvb, offset);
1987
1988         if(parent_tree){
1989                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1990                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1991         }
1992
1993         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
1994         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
1995
1996         offset += 2;
1997
1998         return offset;
1999 }
2000
2001 #define SECURITY_MODE_MODE             0x01
2002 #define SECURITY_MODE_PASSWORD         0x02
2003 #define SECURITY_MODE_SIGNATURES       0x04
2004 #define SECURITY_MODE_SIG_REQUIRED     0x08
2005 static const true_false_string tfs_sm_mode = {
2006         "USER security mode",
2007         "SHARE security mode"
2008 };
2009 static const true_false_string tfs_sm_password = {
2010         "ENCRYPTED password. Use challenge/response",
2011         "PLAINTEXT password"
2012 };
2013 static const true_false_string tfs_sm_signatures = {
2014         "Security signatures ENABLED",
2015         "Security signatures NOT enabled"
2016 };
2017 static const true_false_string tfs_sm_sig_required = {
2018         "Security signatures REQUIRED",
2019         "Security signatures NOT required"
2020 };
2021
2022 static int
2023 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
2024 {
2025         guint16 mask = 0;
2026         proto_item *item = NULL;
2027         proto_tree *tree = NULL;
2028
2029         switch(wc){
2030         case 13:
2031                 mask = tvb_get_letohs(tvb, offset);
2032                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2033                                 "Security Mode: 0x%04x", mask);
2034                 tree = proto_item_add_subtree(item, ett_smb_mode);
2035                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
2036                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
2037                 offset += 2;
2038                 break;
2039
2040         case 17:
2041                 mask = tvb_get_guint8(tvb, offset);
2042                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
2043                                 "Security Mode: 0x%02x", mask);
2044                 tree = proto_item_add_subtree(item, ett_smb_mode);
2045                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2046                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2047                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2048                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2049                 offset += 1;
2050                 break;
2051         }
2052
2053         return offset;
2054 }
2055
2056 static int
2057 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2058 {
2059         proto_item *it = NULL;
2060         proto_tree *tr = NULL;
2061         guint16 bc;
2062         guint8 wc;
2063
2064         WORD_COUNT;
2065
2066         BYTE_COUNT;
2067
2068         if(tree){
2069                 it = proto_tree_add_text(tree, tvb, offset, bc,
2070                                 "Requested Dialects");
2071                 tr = proto_item_add_subtree(it, ett_smb_dialects);
2072         }
2073
2074         while(bc){
2075                 int len;
2076                 const guint8 *str;
2077                 proto_item *dit = NULL;
2078                 proto_tree *dtr = NULL;
2079
2080                 /* XXX - what if this runs past bc? */
2081                 len = tvb_strsize(tvb, offset+1);
2082                 str = tvb_get_ptr(tvb, offset+1, len);
2083
2084                 if(tr){
2085                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2086                                         "Dialect: %s", str);
2087                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2088                 }
2089
2090                 /* Buffer Format */
2091                 CHECK_BYTE_COUNT(1);
2092                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2093                         TRUE);
2094                 COUNT_BYTES(1);
2095
2096                 /*Dialect Name */
2097                 CHECK_BYTE_COUNT(len);
2098                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2099                         len, str);
2100                 COUNT_BYTES(len);
2101         }
2102
2103         END_OF_SMB
2104
2105         return offset;
2106 }
2107
2108 static int
2109 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2110 {
2111         smb_info_t *si = pinfo->private_data;
2112         guint8 wc;
2113         guint16 dialect;
2114         const char *dn;
2115         int dn_len;
2116         guint16 bc;
2117         guint16 ekl=0;
2118         guint32 caps=0;
2119         gint16 tz;
2120
2121         WORD_COUNT;
2122
2123         /* Dialect Index */
2124         dialect = tvb_get_letohs(tvb, offset);
2125         switch(wc){
2126         case 1:
2127                 if(dialect==0xffff){
2128                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2129                                 tvb, offset, 2, dialect,
2130                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2131                 } else {
2132                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2133                                 tvb, offset, 2, dialect);
2134                 }
2135                 break;
2136         case 13:
2137                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2138                         tvb, offset, 2, dialect,
2139                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2140                 break;
2141         case 17:
2142                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2143                         tvb, offset, 2, dialect,
2144                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2145                 break;
2146         default:
2147                 proto_tree_add_text(tree, tvb, offset, wc*2,
2148                         "Words for unknown response format");
2149                 offset += wc*2;
2150                 goto bytecount;
2151         }
2152         offset += 2;
2153
2154         switch(wc){
2155         case 13:
2156                 /* Security Mode */
2157                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2158
2159                 /* Maximum Transmit Buffer Size */
2160                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2161                         tvb, offset, 2, TRUE);
2162                 offset += 2;
2163
2164                 /* Maximum Multiplex Count */
2165                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2166                         tvb, offset, 2, TRUE);
2167                 offset += 2;
2168
2169                 /* Maximum Vcs Number */
2170                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2171                         tvb, offset, 2, TRUE);
2172                 offset += 2;
2173
2174                 /* raw mode */
2175                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2176
2177                 /* session key */
2178                 proto_tree_add_item(tree, hf_smb_session_key,
2179                         tvb, offset, 4, TRUE);
2180                 offset += 4;
2181
2182                 /* current time and date at server */
2183                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2184                     TRUE);
2185
2186                 /* time zone */
2187                 tz = tvb_get_letohs(tvb, offset);
2188                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2189                 offset += 2;
2190
2191                 /* encryption key length */
2192                 ekl = tvb_get_letohs(tvb, offset);
2193                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2194                 offset += 2;
2195
2196                 /* 2 reserved bytes */
2197                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2198                 offset += 2;
2199
2200                 break;
2201
2202         case 17:
2203                 /* Security Mode */
2204                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2205
2206                 /* Maximum Multiplex Count */
2207                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2208                         tvb, offset, 2, TRUE);
2209                 offset += 2;
2210
2211                 /* Maximum Vcs Number */
2212                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2213                         tvb, offset, 2, TRUE);
2214                 offset += 2;
2215
2216                 /* Maximum Transmit Buffer Size */
2217                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2218                         tvb, offset, 4, TRUE);
2219                 offset += 4;
2220
2221                 /* maximum raw buffer size */
2222                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2223                         tvb, offset, 4, TRUE);
2224                 offset += 4;
2225
2226                 /* session key */
2227                 proto_tree_add_item(tree, hf_smb_session_key,
2228                         tvb, offset, 4, TRUE);
2229                 offset += 4;
2230
2231                 /* server capabilities */
2232                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2233                 offset += 4;
2234
2235                 /* system time */
2236                 offset = dissect_smb_64bit_time(tvb, tree, offset,
2237                                 hf_smb_system_time);
2238
2239                 /* time zone */
2240                 tz = tvb_get_letohs(tvb, offset);
2241                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2242                         tvb, offset, 2, tz,
2243                         "Server Time Zone: %d min from UTC", tz);
2244                 offset += 2;
2245
2246                 /* encryption key length */
2247                 ekl = tvb_get_guint8(tvb, offset);
2248                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2249                         tvb, offset, 1, ekl);
2250                 offset += 1;
2251
2252                 break;
2253         }
2254
2255         BYTE_COUNT;
2256
2257         switch(wc){
2258         case 13:
2259                 /* challenge/response encryption key */
2260                 if(ekl){
2261                         CHECK_BYTE_COUNT(ekl);
2262                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2263                         COUNT_BYTES(ekl);
2264                 }
2265
2266                 /*
2267                  * Primary domain.
2268                  *
2269                  * XXX - not present if negotiated dialect isn't
2270                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2271                  * have to see the request, or assume what dialect strings
2272                  * were sent, to determine that.
2273                  *
2274                  * Is this something other than a primary domain if the
2275                  * negotiated dialect is Windows for Workgroups 3.1a?
2276                  * It appears to be 8 bytes of binary data in at least
2277                  * one capture - is that an encryption key or something
2278                  * such as that?
2279                  */
2280                 dn = get_unicode_or_ascii_string(tvb, &offset,
2281                         si->unicode, &dn_len, FALSE, FALSE, &bc);
2282                 if (dn == NULL)
2283                         goto endofcommand;
2284                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2285                         offset, dn_len,dn);
2286                 COUNT_BYTES(dn_len);
2287                 break;
2288
2289         case 17:
2290                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2291                         /* challenge/response encryption key */
2292                         /* XXX - is this aligned on an even boundary? */
2293                         if(ekl){
2294                                 CHECK_BYTE_COUNT(ekl);
2295                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2296                                         tvb, offset, ekl, TRUE);
2297                                 COUNT_BYTES(ekl);
2298                         }
2299
2300                         /* domain */
2301                         /* this string is special, unicode is flagged in caps */
2302                         /* This string is NOT padded to be 16bit aligned.
2303                            (seen in actual capture)
2304                            XXX - I've seen a capture where it appears to be
2305                            so aligned, but I've also seen captures where
2306                            it is.  The captures where it appeared to be
2307                            aligned may have been from buggy servers. */
2308                         /* However, don't get rid of existing setting */
2309                         si->unicode = (caps&SERVER_CAP_UNICODE) ||
2310                           si->unicode;
2311
2312                         dn = get_unicode_or_ascii_string(tvb,
2313                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2314                                 &bc);
2315                         if (dn == NULL)
2316                                 goto endofcommand;
2317                         proto_tree_add_string(tree, hf_smb_primary_domain,
2318                                 tvb, offset, dn_len, dn);
2319                         COUNT_BYTES(dn_len);
2320
2321                         /* server name, seen in w2k pro capture */
2322                         dn = get_unicode_or_ascii_string(tvb,
2323                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2324                                 &bc);
2325                         if (dn == NULL)
2326                                 goto endofcommand;
2327                         proto_tree_add_string(tree, hf_smb_server,
2328                                 tvb, offset, dn_len, dn);
2329                         COUNT_BYTES(dn_len);
2330
2331                 } else {
2332                         proto_item *blob_item;
2333
2334                         /* guid */
2335                         /* XXX - show it in the standard Microsoft format
2336                            for GUIDs? */
2337                         CHECK_BYTE_COUNT(16);
2338                         proto_tree_add_item(tree, hf_smb_server_guid,
2339                                 tvb, offset, 16, TRUE);
2340                         COUNT_BYTES(16);
2341
2342                         blob_item = proto_tree_add_item(
2343                                 tree, hf_smb_security_blob,
2344                                 tvb, offset, bc, TRUE);
2345
2346                         /* security blob */
2347                         /* 
2348                          * If Extended security and BCC == 16, then raw 
2349                          * NTLMSSP is in use. We need to save this info
2350                          */
2351  
2352                         if(bc){
2353                                 tvbuff_t *gssapi_tvb;
2354                                 proto_tree *gssapi_tree;
2355
2356                                 gssapi_tree = proto_item_add_subtree(
2357                                         blob_item, ett_smb_secblob);
2358
2359                                 gssapi_tvb = tvb_new_subset(
2360                                         tvb, offset, bc, bc);
2361
2362                                 call_dissector(
2363                                         gssapi_handle, gssapi_tvb, pinfo,
2364                                         gssapi_tree);
2365
2366                                 if (si->ct)
2367                                   si->ct->raw_ntlmssp = 0;
2368
2369                                 COUNT_BYTES(bc);
2370                         }
2371                         else { 
2372
2373                           /*
2374                            * There is no blob. We just have to make sure
2375                            * that subsequent routines know to call the 
2376                            * right things ...
2377                            */
2378
2379                           if (si->ct)
2380                             si->ct->raw_ntlmssp = 1;
2381
2382                         }
2383                 }
2384                 break;
2385         }
2386
2387         END_OF_SMB
2388
2389         return offset;
2390 }
2391
2392
2393 static int
2394 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2395 {
2396         smb_info_t *si = pinfo->private_data;
2397         int dn_len;
2398         const char *dn;
2399         guint8 wc;
2400         guint16 bc;
2401
2402         WORD_COUNT;
2403
2404         BYTE_COUNT;
2405
2406         /* buffer format */
2407         CHECK_BYTE_COUNT(1);
2408         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2409         COUNT_BYTES(1);
2410
2411         /* dir name */
2412         dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
2413                 FALSE, FALSE, &bc);
2414         if (dn == NULL)
2415                 goto endofcommand;
2416         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2417                 dn);
2418         COUNT_BYTES(dn_len);
2419
2420         if (check_col(pinfo->cinfo, COL_INFO)) {
2421                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s", dn);
2422         }
2423
2424         END_OF_SMB
2425
2426         return offset;
2427 }
2428
2429 static int
2430 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2431 {
2432         guint8 wc;
2433         guint16 bc;
2434
2435         WORD_COUNT;
2436
2437         BYTE_COUNT;
2438
2439         END_OF_SMB
2440
2441         return offset;
2442 }
2443
2444 static int
2445 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2446 {
2447         guint16 ec, bc;
2448         guint8 wc;
2449
2450         WORD_COUNT;
2451
2452         /* echo count */
2453         ec = tvb_get_letohs(tvb, offset);
2454         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2455         offset += 2;
2456
2457         BYTE_COUNT;
2458
2459         if (bc != 0) {
2460                 /* echo data */
2461                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2462                 COUNT_BYTES(bc);
2463         }
2464
2465         END_OF_SMB
2466
2467         return offset;
2468 }
2469
2470 static int
2471 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2472 {
2473         guint16 bc;
2474         guint8 wc;
2475
2476         WORD_COUNT;
2477
2478         /* echo sequence number */
2479         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2480         offset += 2;
2481
2482         BYTE_COUNT;
2483
2484         if (bc != 0) {
2485                 /* echo data */
2486                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2487                 COUNT_BYTES(bc);
2488         }
2489
2490         END_OF_SMB
2491
2492         return offset;
2493 }
2494
2495 static int
2496 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2497 {
2498         smb_info_t *si = pinfo->private_data;
2499         int an_len, pwlen;
2500         const char *an;
2501         guint8 wc;
2502         guint16 bc;
2503
2504         WORD_COUNT;
2505
2506         BYTE_COUNT;
2507
2508         /* buffer format */
2509         CHECK_BYTE_COUNT(1);
2510         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2511         COUNT_BYTES(1);
2512
2513         /* Path */
2514         an = get_unicode_or_ascii_string(tvb, &offset,
2515                 si->unicode, &an_len, FALSE, FALSE, &bc);
2516         if (an == NULL)
2517                 goto endofcommand;
2518         proto_tree_add_string(tree, hf_smb_path, tvb,
2519                 offset, an_len, an);
2520         COUNT_BYTES(an_len);
2521
2522         if (check_col(pinfo->cinfo, COL_INFO)) {
2523                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
2524         }
2525
2526         /* buffer format */
2527         CHECK_BYTE_COUNT(1);
2528         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2529         COUNT_BYTES(1);
2530
2531         /* password, ANSI */
2532         /* XXX - what if this runs past bc? */
2533         pwlen = tvb_strsize(tvb, offset);
2534         CHECK_BYTE_COUNT(pwlen);
2535         proto_tree_add_item(tree, hf_smb_password,
2536                 tvb, offset, pwlen, TRUE);
2537         COUNT_BYTES(pwlen);
2538
2539         /* buffer format */
2540         CHECK_BYTE_COUNT(1);
2541         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2542         COUNT_BYTES(1);
2543
2544         /* Service */
2545         an = get_unicode_or_ascii_string(tvb, &offset,
2546                 si->unicode, &an_len, FALSE, FALSE, &bc);
2547         if (an == NULL)
2548                 goto endofcommand;
2549         proto_tree_add_string(tree, hf_smb_service, tvb,
2550                 offset, an_len, an);
2551         COUNT_BYTES(an_len);
2552
2553         END_OF_SMB
2554
2555         return offset;
2556 }
2557
2558 static int
2559 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2560 {
2561         guint8 wc;
2562         guint16 bc;
2563
2564         WORD_COUNT;
2565
2566         /* Maximum Buffer Size */
2567         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2568         offset += 2;
2569
2570         /* tid */
2571         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2572         offset += 2;
2573
2574         BYTE_COUNT;
2575
2576         END_OF_SMB
2577
2578         return offset;
2579 }
2580
2581
2582 static const true_false_string tfs_of_create = {
2583         "Create file if it does not exist",
2584         "Fail if file does not exist"
2585 };
2586 static const value_string of_open[] = {
2587         { 0,            "Fail if file exists"},
2588         { 1,            "Open file if it exists"},
2589         { 2,            "Truncate file if it exists"},
2590         {0, NULL}
2591 };
2592 static int
2593 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2594 {
2595         guint16 mask;
2596         proto_item *item = NULL;
2597         proto_tree *tree = NULL;
2598
2599         mask = tvb_get_letohs(tvb, offset);
2600
2601         if(parent_tree){
2602                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2603                         "Open Function: 0x%04x", mask);
2604                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2605         }
2606
2607         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2608                 tvb, offset, 2, mask);
2609         proto_tree_add_uint(tree, hf_smb_open_function_open,
2610                 tvb, offset, 2, mask);
2611
2612         offset += 2;
2613
2614         return offset;
2615 }
2616
2617
2618 static const true_false_string tfs_mf_file = {
2619         "Target must be a file",
2620         "Target needn't be a file"
2621 };
2622 static const true_false_string tfs_mf_dir = {
2623         "Target must be a directory",
2624         "Target needn't be a directory"
2625 };
2626 static const true_false_string tfs_mf_verify = {
2627         "MUST verify all writes",
2628         "Don't have to verify writes"
2629 };
2630 static int
2631 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2632 {
2633         guint16 mask;
2634         proto_item *item = NULL;
2635         proto_tree *tree = NULL;
2636
2637         mask = tvb_get_letohs(tvb, offset);
2638
2639         if(parent_tree){
2640                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2641                         "Flags: 0x%04x", mask);
2642                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2643         }
2644
2645         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2646                 tvb, offset, 2, mask);
2647         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2648                 tvb, offset, 2, mask);
2649         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2650                 tvb, offset, 2, mask);
2651
2652         offset += 2;
2653
2654         return offset;
2655 }
2656
2657 static const true_false_string tfs_cf_mode = {
2658         "ASCII",
2659         "Binary"
2660 };
2661 static const true_false_string tfs_cf_tree_copy = {
2662         "Copy is a tree copy",
2663         "Copy is a file copy"
2664 };
2665 static const true_false_string tfs_cf_ea_action = {
2666         "Fail copy",
2667         "Discard EAs"
2668 };
2669 static int
2670 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2671 {
2672         guint16 mask;
2673         proto_item *item = NULL;
2674         proto_tree *tree = NULL;
2675
2676         mask = tvb_get_letohs(tvb, offset);
2677
2678         if(parent_tree){
2679                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2680                         "Flags: 0x%04x", mask);
2681                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2682         }
2683
2684         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
2685                 tvb, offset, 2, mask);
2686         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2687                 tvb, offset, 2, mask);
2688         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2689                 tvb, offset, 2, mask);
2690         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2691                 tvb, offset, 2, mask);
2692         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2693                 tvb, offset, 2, mask);
2694         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2695                 tvb, offset, 2, mask);
2696         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2697                 tvb, offset, 2, mask);
2698
2699         offset += 2;
2700
2701         return offset;
2702 }
2703
2704 static int
2705 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2706 {
2707         smb_info_t *si = pinfo->private_data;
2708         int fn_len;
2709         guint16 tid;
2710         guint16 bc;
2711         guint8 wc;
2712         const char *fn;
2713
2714         WORD_COUNT;
2715
2716         /* tid */
2717         tid = tvb_get_letohs(tvb, offset);
2718         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2719                 "TID (target): 0x%04x", tid);
2720         offset += 2;
2721
2722         /* open function */
2723         offset = dissect_open_function(tvb, tree, offset);
2724
2725         /* move flags */
2726         offset = dissect_move_flags(tvb, tree, offset);
2727
2728         BYTE_COUNT;
2729
2730         /* buffer format */
2731         CHECK_BYTE_COUNT(1);
2732         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2733         COUNT_BYTES(1);
2734
2735         /* file name */
2736         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2737                 FALSE, FALSE, &bc);
2738         if (fn == NULL)
2739                 goto endofcommand;
2740         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2741                 fn_len, fn, "Old File Name: %s", fn);
2742         COUNT_BYTES(fn_len);
2743
2744         if (check_col(pinfo->cinfo, COL_INFO)) {
2745                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2746         }
2747
2748         /* buffer format */
2749         CHECK_BYTE_COUNT(1);
2750         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2751         COUNT_BYTES(1);
2752
2753         /* file name */
2754         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2755                 FALSE, FALSE, &bc);
2756         if (fn == NULL)
2757                 goto endofcommand;
2758         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2759                 fn_len, fn, "New File Name: %s", fn);
2760         COUNT_BYTES(fn_len);
2761
2762         if (check_col(pinfo->cinfo, COL_INFO)) {
2763                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2764         }
2765
2766         END_OF_SMB
2767
2768         return offset;
2769 }
2770
2771 static int
2772 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2773 {
2774         smb_info_t *si = pinfo->private_data;
2775         int fn_len;
2776         guint16 tid;
2777         guint16 bc;
2778         guint8 wc;
2779         const char *fn;
2780
2781         WORD_COUNT;
2782
2783         /* tid */
2784         tid = tvb_get_letohs(tvb, offset);
2785         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2786                 "TID (target): 0x%04x", tid);
2787         offset += 2;
2788
2789         /* open function */
2790         offset = dissect_open_function(tvb, tree, offset);
2791
2792         /* copy flags */
2793         offset = dissect_copy_flags(tvb, tree, offset);
2794
2795         BYTE_COUNT;
2796
2797         /* buffer format */
2798         CHECK_BYTE_COUNT(1);
2799         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2800         COUNT_BYTES(1);
2801
2802         /* file name */
2803         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2804                 FALSE, FALSE, &bc);
2805         if (fn == NULL)
2806                 goto endofcommand;
2807         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2808                 fn_len, fn, "Source File Name: %s", fn);
2809         COUNT_BYTES(fn_len);
2810
2811         if (check_col(pinfo->cinfo, COL_INFO)) {
2812                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s", fn);
2813         }
2814
2815         /* buffer format */
2816         CHECK_BYTE_COUNT(1);
2817         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2818         COUNT_BYTES(1);
2819
2820         /* file name */
2821         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2822                 FALSE, FALSE, &bc);
2823         if (fn == NULL)
2824                 goto endofcommand;
2825         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2826                 fn_len, fn, "Destination File Name: %s", fn);
2827         COUNT_BYTES(fn_len);
2828
2829         if (check_col(pinfo->cinfo, COL_INFO)) {
2830                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", fn);
2831         }
2832
2833         END_OF_SMB
2834
2835         return offset;
2836 }
2837
2838 static int
2839 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2840 {
2841         smb_info_t *si = pinfo->private_data;
2842         int fn_len;
2843         const char *fn;
2844         guint8 wc;
2845         guint16 bc;
2846
2847         WORD_COUNT;
2848
2849         /* # of files moved */
2850         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
2851         offset += 2;
2852
2853         BYTE_COUNT;
2854
2855         /* buffer format */
2856         CHECK_BYTE_COUNT(1);
2857         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2858         COUNT_BYTES(1);
2859
2860         /* file name */
2861         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2862                 FALSE, FALSE, &bc);
2863         if (fn == NULL)
2864                 goto endofcommand;
2865         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2866                 fn);
2867         COUNT_BYTES(fn_len);
2868
2869         END_OF_SMB
2870
2871         return offset;
2872 }
2873
2874 static int
2875 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2876 {
2877         smb_info_t *si = pinfo->private_data;
2878         int fn_len;
2879         const char *fn;
2880         guint8 wc;
2881         guint16 bc;
2882
2883         WORD_COUNT;
2884
2885         /* desired access */
2886         offset = dissect_access(tvb, tree, offset, "Desired");
2887
2888         /* Search Attributes */
2889         offset = dissect_search_attributes(tvb, tree, offset);
2890
2891         BYTE_COUNT;
2892
2893         /* buffer format */
2894         CHECK_BYTE_COUNT(1);
2895         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2896         COUNT_BYTES(1);
2897
2898         /* file name */
2899         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2900                 FALSE, FALSE, &bc);
2901         if (fn == NULL)
2902                 goto endofcommand;
2903         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2904                 fn);
2905         COUNT_BYTES(fn_len);
2906
2907         if (check_col(pinfo->cinfo, COL_INFO)) {
2908                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2909         }
2910
2911         END_OF_SMB
2912
2913         return offset;
2914 }
2915
2916 void
2917 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2918     int len, guint16 fid)
2919 {
2920         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2921         if (check_col(pinfo->cinfo, COL_INFO))
2922                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2923 }
2924
2925 static int
2926 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2927 {
2928         guint8 wc;
2929         guint16 bc;
2930         guint16 fid;
2931
2932         WORD_COUNT;
2933
2934         /* fid */
2935         fid = tvb_get_letohs(tvb, offset);
2936         add_fid(tvb, pinfo, tree, offset, 2, fid);
2937         offset += 2;
2938
2939         /* File Attributes */
2940         offset = dissect_file_attributes(tvb, tree, offset, 2);
2941
2942         /* last write time */
2943         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2944
2945         /* File Size */
2946         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2947         offset += 4;
2948
2949         /* granted access */
2950         offset = dissect_access(tvb, tree, offset, "Granted");
2951
2952         BYTE_COUNT;
2953
2954         END_OF_SMB
2955
2956         return offset;
2957 }
2958
2959 static int
2960 dissect_fid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2961 {
2962         guint8 wc;
2963         guint16 bc;
2964         guint16 fid;
2965
2966         WORD_COUNT;
2967
2968         /* fid */
2969         fid = tvb_get_letohs(tvb, offset);
2970         add_fid(tvb, pinfo, tree, offset, 2, fid);
2971         offset += 2;
2972
2973         BYTE_COUNT;
2974
2975         END_OF_SMB
2976
2977         return offset;
2978 }
2979
2980 static int
2981 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2982 {
2983         smb_info_t *si = pinfo->private_data;
2984         int fn_len;
2985         const char *fn;
2986         guint8 wc;
2987         guint16 bc;
2988
2989         WORD_COUNT;
2990
2991         /* file attributes */
2992         offset = dissect_file_attributes(tvb, tree, offset, 2);
2993
2994         /* creation time */
2995         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
2996
2997         BYTE_COUNT;
2998
2999         /* buffer format */
3000         CHECK_BYTE_COUNT(1);
3001         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3002         COUNT_BYTES(1);
3003
3004         /* File Name */
3005         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3006                 FALSE, FALSE, &bc);
3007         if (fn == NULL)
3008                 goto endofcommand;
3009         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3010                 fn);
3011         COUNT_BYTES(fn_len);
3012
3013         if (check_col(pinfo->cinfo, COL_INFO)) {
3014                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3015         }
3016
3017         END_OF_SMB
3018
3019         return offset;
3020 }
3021
3022 static int
3023 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3024 {
3025         guint8 wc;
3026         guint16 bc, fid;
3027
3028         WORD_COUNT;
3029
3030         /* fid */
3031         fid = tvb_get_letohs(tvb, offset);
3032         add_fid(tvb, pinfo, tree, offset, 2, fid);
3033         offset += 2;
3034
3035         /* last write time */
3036         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3037
3038         BYTE_COUNT;
3039
3040         END_OF_SMB
3041
3042         return offset;
3043 }
3044
3045 static int
3046 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3047 {
3048         smb_info_t *si = pinfo->private_data;
3049         int fn_len;
3050         const char *fn;
3051         guint8 wc;
3052         guint16 bc;
3053
3054         WORD_COUNT;
3055
3056         /* search attributes */
3057         offset = dissect_search_attributes(tvb, tree, offset);
3058
3059         BYTE_COUNT;
3060
3061         /* buffer format */
3062         CHECK_BYTE_COUNT(1);
3063         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3064         COUNT_BYTES(1);
3065
3066         /* file name */
3067         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3068                 FALSE, FALSE, &bc);
3069         if (fn == NULL)
3070                 goto endofcommand;
3071         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3072                 fn);
3073         COUNT_BYTES(fn_len);
3074
3075         if (check_col(pinfo->cinfo, COL_INFO)) {
3076                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3077         }
3078
3079         END_OF_SMB
3080
3081         return offset;
3082 }
3083
3084 static int
3085 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3086 {
3087         smb_info_t *si = pinfo->private_data;
3088         int fn_len;
3089         const char *fn;
3090         guint8 wc;
3091         guint16 bc;
3092
3093         WORD_COUNT;
3094
3095         /* search attributes */
3096         offset = dissect_search_attributes(tvb, tree, offset);
3097
3098         BYTE_COUNT;
3099
3100         /* buffer format */
3101         CHECK_BYTE_COUNT(1);
3102         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3103         COUNT_BYTES(1);
3104
3105         /* old file name */
3106         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3107                 FALSE, FALSE, &bc);
3108         if (fn == NULL)
3109                 goto endofcommand;
3110         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3111                 fn);
3112         COUNT_BYTES(fn_len);
3113
3114         if (check_col(pinfo->cinfo, COL_INFO)) {
3115                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3116         }
3117
3118         /* buffer format */
3119         CHECK_BYTE_COUNT(1);
3120         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3121         COUNT_BYTES(1);
3122
3123         /* file name */
3124         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3125                 FALSE, FALSE, &bc);
3126         if (fn == NULL)
3127                 goto endofcommand;
3128         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3129                 fn);
3130         COUNT_BYTES(fn_len);
3131
3132         if (check_col(pinfo->cinfo, COL_INFO)) {
3133                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3134         }
3135
3136         END_OF_SMB
3137
3138         return offset;
3139 }
3140
3141 static int
3142 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3143 {
3144         smb_info_t *si = pinfo->private_data;
3145         int fn_len;
3146         const char *fn;
3147         guint8 wc;
3148         guint16 bc;
3149
3150         WORD_COUNT;
3151
3152         /* search attributes */
3153         offset = dissect_search_attributes(tvb, tree, offset);
3154
3155         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3156         offset += 2;
3157
3158         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3159         offset += 4;
3160
3161         BYTE_COUNT;
3162
3163         /* buffer format */
3164         CHECK_BYTE_COUNT(1);
3165         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3166         COUNT_BYTES(1);
3167
3168         /* old file name */
3169         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3170                 FALSE, FALSE, &bc);
3171         if (fn == NULL)
3172                 goto endofcommand;
3173         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3174                 fn);
3175         COUNT_BYTES(fn_len);
3176
3177         if (check_col(pinfo->cinfo, COL_INFO)) {
3178                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3179         }
3180
3181         /* buffer format */
3182         CHECK_BYTE_COUNT(1);
3183         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3184         COUNT_BYTES(1);
3185
3186         /* file name */
3187         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3188                 FALSE, FALSE, &bc);
3189         if (fn == NULL)
3190                 goto endofcommand;
3191         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3192                 fn);
3193         COUNT_BYTES(fn_len);
3194
3195         if (check_col(pinfo->cinfo, COL_INFO)) {
3196                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3197         }
3198
3199         END_OF_SMB
3200
3201         return offset;
3202 }
3203
3204
3205 static int
3206 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3207 {
3208         smb_info_t *si = pinfo->private_data;
3209         guint16 bc;
3210         guint8 wc;
3211         const char *fn;
3212         int fn_len;
3213
3214         WORD_COUNT;
3215
3216         BYTE_COUNT;
3217
3218         /* Buffer Format */
3219         CHECK_BYTE_COUNT(1);
3220         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3221         COUNT_BYTES(1);
3222
3223         /* File Name */
3224         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3225                 FALSE, FALSE, &bc);
3226         if (fn == NULL)
3227                 goto endofcommand;
3228         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3229                 fn);
3230         COUNT_BYTES(fn_len);
3231
3232         if (check_col(pinfo->cinfo, COL_INFO)) {
3233                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3234         }
3235
3236         END_OF_SMB
3237
3238         return offset;
3239 }
3240
3241 static int
3242 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3243 {
3244         guint16 bc;
3245         guint8 wc;
3246
3247         WORD_COUNT;
3248
3249         /* File Attributes */
3250         offset = dissect_file_attributes(tvb, tree, offset, 2);
3251
3252         /* Last Write Time */
3253         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3254
3255         /* File Size */
3256         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3257         offset += 4;
3258
3259         /* 10 reserved bytes */
3260         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3261         offset += 10;
3262
3263         BYTE_COUNT;
3264
3265         END_OF_SMB
3266
3267         return offset;
3268 }
3269
3270 static int
3271 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3272 {
3273         smb_info_t *si = pinfo->private_data;
3274         int fn_len;
3275         const char *fn;
3276         guint8 wc;
3277         guint16 bc;
3278
3279         WORD_COUNT;
3280
3281         /* file attributes */
3282         offset = dissect_file_attributes(tvb, tree, offset, 2);
3283
3284         /* last write time */
3285         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3286
3287         /* 10 reserved bytes */
3288         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3289         offset += 10;
3290
3291         BYTE_COUNT;
3292
3293         /* buffer format */
3294         CHECK_BYTE_COUNT(1);
3295         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3296         COUNT_BYTES(1);
3297
3298         /* file name */
3299         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3300                 FALSE, FALSE, &bc);
3301         if (fn == NULL)
3302                 goto endofcommand;
3303         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3304                 fn);
3305         COUNT_BYTES(fn_len);
3306
3307         if (check_col(pinfo->cinfo, COL_INFO)) {
3308                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3309         }
3310
3311         END_OF_SMB
3312
3313         return offset;
3314 }
3315
3316 static int
3317 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3318 {
3319         guint8 wc;
3320         guint16 cnt=0, bc;
3321         guint32 ofs=0;
3322         smb_info_t *si;
3323         unsigned int fid;
3324
3325         WORD_COUNT;
3326
3327         /* fid */
3328         fid = tvb_get_letohs(tvb, offset);
3329         add_fid(tvb, pinfo, tree, offset, 2, fid);
3330         offset += 2;
3331         if (!pinfo->fd->flags.visited) {
3332                 /* remember the FID for the processing of the response */
3333                 si = (smb_info_t *)pinfo->private_data;
3334                 si->sip->extra_info=(void *)fid;
3335         }
3336
3337         /* read count */
3338         cnt = tvb_get_letohs(tvb, offset);
3339         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3340         offset += 2;
3341
3342         /* offset */
3343         ofs = tvb_get_letohl(tvb, offset);
3344         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3345         offset += 4;
3346
3347         if (check_col(pinfo->cinfo, COL_INFO))
3348                 col_append_fstr(pinfo->cinfo, COL_INFO,
3349                                 ", %u byte%s at offset %u", cnt,
3350                                 (cnt == 1) ? "" : "s", ofs);
3351
3352         /* remaining */
3353         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3354         offset += 2;
3355
3356         BYTE_COUNT;
3357
3358         END_OF_SMB
3359
3360         return offset;
3361 }
3362
3363 int
3364 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3365 {
3366         int tvblen;
3367
3368         if(bc>datalen){
3369                 /* We have some initial padding bytes. */
3370                 /* XXX - use the data offset here instead? */
3371                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3372                         TRUE);
3373                 offset += bc-datalen;
3374                 bc = datalen;
3375         }
3376         tvblen = tvb_length_remaining(tvb, offset);
3377         if(bc>tvblen){
3378                 proto_tree_add_bytes_format(tree, hf_smb_file_data, tvb, offset, tvblen, tvb_get_ptr(tvb, offset, tvblen),"File Data: Incomplete. Only %d of %u bytes", tvblen, bc);
3379                 offset += tvblen;
3380         } else {
3381                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3382                 offset += bc;
3383         }
3384         return offset;
3385 }
3386
3387 static int
3388 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3389     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
3390 {
3391         int tvblen;
3392         tvbuff_t *dcerpc_tvb;
3393
3394         if(bc>datalen){
3395                 /* We have some initial padding bytes. */
3396                 /* XXX - use the data offset here instead? */
3397                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3398                         TRUE);
3399                 offset += bc-datalen;
3400                 bc = datalen;
3401         }
3402         tvblen = tvb_length_remaining(tvb, offset);
3403         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
3404         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
3405         if(bc>tvblen)
3406                 offset += tvblen;
3407         else
3408                 offset += bc;
3409         return offset;
3410 }
3411
3412 /*
3413  * transporting DCERPC over SMB seems to be implemented in various
3414  * ways. We might just assume it can be done by an almost random
3415  * mix of Trans/Read/Write calls
3416  *
3417  * if we suspect dcerpc, just send them all down to packet-smb-pipe.c
3418  * and let him sort them out
3419  */
3420 static int
3421 dissect_file_data_maybe_dcerpc(tvbuff_t *tvb, packet_info *pinfo,
3422     proto_tree *tree, proto_tree *top_tree, int offset, guint16 bc,
3423     guint16 datalen, guint32 ofs, guint16 fid)
3424 {
3425         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3426
3427         if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
3428                 /* dcerpc call */
3429                 return dissect_file_data_dcerpc(tvb, pinfo, tree,
3430                     top_tree, offset, bc, datalen, fid);
3431         } else {
3432                 /* ordinary file data */
3433                 return dissect_file_data(tvb, tree, offset, bc, datalen);
3434         }
3435 }
3436
3437 static int
3438 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3439 {
3440         guint16 cnt=0, bc;
3441         guint8 wc;
3442         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3443         int fid=0;
3444
3445         WORD_COUNT;
3446
3447         /* read count */
3448         cnt = tvb_get_letohs(tvb, offset);
3449         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3450         offset += 2;
3451
3452         /* 8 reserved bytes */
3453         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3454         offset += 8;
3455
3456         /* If we have seen the request, then print which FID this refers to */
3457         /* first check if we have seen the request */
3458         if(si->sip != NULL && si->sip->frame_req>0){
3459                 fid=(int)si->sip->extra_info;
3460                 add_fid(tvb, pinfo, tree, 0, 0, fid);
3461         }
3462
3463         BYTE_COUNT;
3464
3465         /* buffer format */
3466         CHECK_BYTE_COUNT(1);
3467         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3468         COUNT_BYTES(1);
3469
3470         /* data len */
3471         CHECK_BYTE_COUNT(2);
3472         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3473         COUNT_BYTES(2);
3474
3475         /* file data, might be DCERPC on a pipe */
3476         if(bc){
3477                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3478                     top_tree, offset, bc, bc, 0, fid);
3479                 bc = 0;
3480         }
3481
3482         END_OF_SMB
3483
3484         return offset;
3485 }
3486
3487 static int
3488 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3489 {
3490         guint16 cnt, bc;
3491         guint8 wc;
3492
3493         WORD_COUNT;
3494
3495         /* read count */
3496         cnt = tvb_get_letohs(tvb, offset);
3497         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3498         offset += 2;
3499
3500         /* 8 reserved bytes */
3501         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3502         offset += 8;
3503
3504         BYTE_COUNT;
3505
3506         /* buffer format */
3507         CHECK_BYTE_COUNT(1);
3508         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3509         COUNT_BYTES(1);
3510
3511         /* data len */
3512         CHECK_BYTE_COUNT(2);
3513         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3514         COUNT_BYTES(2);
3515
3516         END_OF_SMB
3517
3518         return offset;
3519 }
3520
3521
3522 static int
3523 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3524 {
3525         guint32 ofs=0;
3526         guint16 cnt=0, bc, fid=0;
3527         guint8 wc;
3528
3529         WORD_COUNT;
3530
3531         /* fid */
3532         fid = tvb_get_letohs(tvb, offset);
3533         add_fid(tvb, pinfo, tree, offset, 2, fid);
3534         offset += 2;
3535
3536         /* write count */
3537         cnt = tvb_get_letohs(tvb, offset);
3538         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3539         offset += 2;
3540
3541         /* offset */
3542         ofs = tvb_get_letohl(tvb, offset);
3543         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3544         offset += 4;
3545
3546         if (check_col(pinfo->cinfo, COL_INFO))
3547                 col_append_fstr(pinfo->cinfo, COL_INFO,
3548                                 ", %u byte%s at offset %u", cnt,
3549                                 (cnt == 1) ? "" : "s", ofs);
3550
3551         /* remaining */
3552         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3553         offset += 2;
3554
3555         BYTE_COUNT;
3556
3557         /* buffer format */
3558         CHECK_BYTE_COUNT(1);
3559         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3560         COUNT_BYTES(1);
3561
3562         /* data len */
3563         CHECK_BYTE_COUNT(2);
3564         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3565         COUNT_BYTES(2);
3566
3567         /* file data, might be DCERPC on a pipe */
3568         if (bc != 0) {
3569                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3570                     top_tree, offset, bc, bc, ofs, fid);
3571                 bc = 0;
3572         }
3573
3574         END_OF_SMB
3575
3576         return offset;
3577 }
3578
3579 static int
3580 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3581 {
3582         guint8 wc;
3583         guint16 bc, cnt;
3584
3585         WORD_COUNT;
3586
3587         /* write count */
3588         cnt = tvb_get_letohs(tvb, offset);
3589         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3590         offset += 2;
3591
3592         if (check_col(pinfo->cinfo, COL_INFO))
3593                 col_append_fstr(pinfo->cinfo, COL_INFO,
3594                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
3595
3596         BYTE_COUNT;
3597
3598         END_OF_SMB
3599
3600         return offset;
3601 }
3602
3603 static int
3604 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3605 {
3606         guint8 wc;
3607         guint16 bc, fid;
3608
3609         WORD_COUNT;
3610
3611         /* fid */
3612         fid = tvb_get_letohs(tvb, offset);
3613         add_fid(tvb, pinfo, tree, offset, 2, fid);
3614         offset += 2;
3615
3616         /* lock count */
3617         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3618         offset += 4;
3619
3620         /* offset */
3621         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3622         offset += 4;
3623
3624         BYTE_COUNT;
3625
3626         END_OF_SMB
3627
3628         return offset;
3629 }
3630
3631 static int
3632 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3633 {
3634         smb_info_t *si = pinfo->private_data;
3635         int fn_len;
3636         const char *fn;
3637         guint8 wc;
3638         guint16 bc;
3639
3640         WORD_COUNT;
3641
3642         /* 2 reserved bytes */
3643         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3644         offset += 2;
3645
3646         /* Creation time */
3647         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3648
3649         BYTE_COUNT;
3650
3651         /* buffer format */
3652         CHECK_BYTE_COUNT(1);
3653         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3654         COUNT_BYTES(1);
3655
3656         /* directory name */
3657         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3658                 FALSE, FALSE, &bc);
3659         if (fn == NULL)
3660                 goto endofcommand;
3661         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3662                 fn);
3663         COUNT_BYTES(fn_len);
3664
3665         if (check_col(pinfo->cinfo, COL_INFO)) {
3666                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3667         }
3668
3669         END_OF_SMB
3670
3671         return offset;
3672 }
3673
3674 static int
3675 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3676 {
3677         smb_info_t *si = pinfo->private_data;
3678         int fn_len;
3679         const char *fn;
3680         guint8 wc;
3681         guint16 bc, fid;
3682
3683         WORD_COUNT;
3684
3685         /* fid */
3686         fid = tvb_get_letohs(tvb, offset);
3687         add_fid(tvb, pinfo, tree, offset, 2, fid);
3688         offset += 2;
3689
3690         BYTE_COUNT;
3691
3692         /* buffer format */
3693         CHECK_BYTE_COUNT(1);
3694         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3695         COUNT_BYTES(1);
3696
3697         /* file name */
3698         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3699                 FALSE, FALSE, &bc);
3700         if (fn == NULL)
3701                 goto endofcommand;
3702         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3703                 fn);
3704         COUNT_BYTES(fn_len);
3705
3706         END_OF_SMB
3707
3708         return offset;
3709 }
3710
3711 static const value_string seek_mode_vals[] = {
3712         {0,     "From Start Of File"},
3713         {1,     "From Current Position"},
3714         {2,     "From End Of File"},
3715         {0,     NULL}
3716 };
3717
3718 static int
3719 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3720 {
3721         guint8 wc;
3722         guint16 bc, fid;
3723
3724         WORD_COUNT;
3725
3726         /* fid */
3727         fid = tvb_get_letohs(tvb, offset);
3728         add_fid(tvb, pinfo, tree, offset, 2, fid);
3729         offset += 2;
3730
3731         /* Seek Mode */
3732         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3733         offset += 2;
3734
3735         /* offset */
3736         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3737         offset += 4;
3738
3739         BYTE_COUNT;
3740
3741         END_OF_SMB
3742
3743         return offset;
3744 }
3745
3746 static int
3747 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3748 {
3749         guint8 wc;
3750         guint16 bc;
3751
3752         WORD_COUNT;
3753
3754         /* offset */
3755         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3756         offset += 4;
3757
3758         BYTE_COUNT;
3759
3760         END_OF_SMB
3761
3762         return offset;
3763 }
3764
3765 static int
3766 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3767 {
3768         guint8 wc;
3769         guint16 bc, fid;
3770
3771         WORD_COUNT;
3772
3773         /* fid */
3774         fid = tvb_get_letohs(tvb, offset);
3775         add_fid(tvb, pinfo, tree, offset, 2, fid);
3776         offset += 2;
3777
3778         /* create time */
3779         offset = dissect_smb_datetime(tvb, tree, offset,
3780                 hf_smb_create_time,
3781                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3782
3783         /* access time */
3784         offset = dissect_smb_datetime(tvb, tree, offset,
3785                 hf_smb_access_time,
3786                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3787
3788         /* last write time */
3789         offset = dissect_smb_datetime(tvb, tree, offset,
3790                 hf_smb_last_write_time,
3791                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3792
3793         BYTE_COUNT;
3794
3795         END_OF_SMB
3796
3797         return offset;
3798 }
3799
3800 static int
3801 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3802 {
3803         guint8 wc;
3804         guint16 bc;
3805
3806         WORD_COUNT;
3807
3808         /* create time */
3809         offset = dissect_smb_datetime(tvb, tree, offset,
3810                 hf_smb_create_time,
3811                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3812
3813         /* access time */
3814         offset = dissect_smb_datetime(tvb, tree, offset,
3815                 hf_smb_access_time,
3816                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3817
3818         /* last write time */
3819         offset = dissect_smb_datetime(tvb, tree, offset,
3820                 hf_smb_last_write_time,
3821                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3822
3823         /* data size */
3824         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3825         offset += 4;
3826
3827         /* allocation size */
3828         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3829         offset += 4;
3830
3831         /* File Attributes */
3832         offset = dissect_file_attributes(tvb, tree, offset, 2);
3833
3834         BYTE_COUNT;
3835
3836         END_OF_SMB
3837
3838         return offset;
3839 }
3840
3841 static int
3842 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3843 {
3844         guint8 wc;
3845         guint16 cnt=0;
3846         guint16 bc, fid;
3847
3848         WORD_COUNT;
3849
3850         /* fid */
3851         fid = tvb_get_letohs(tvb, offset);
3852         add_fid(tvb, pinfo, tree, offset, 2, fid);
3853         offset += 2;
3854
3855         /* write count */
3856         cnt = tvb_get_letohs(tvb, offset);
3857         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3858         offset += 2;
3859
3860         /* offset */
3861         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3862         offset += 4;
3863
3864         /* last write time */
3865         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3866
3867         if(wc==12){
3868                 /* 12 reserved bytes */
3869                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3870                 offset += 12;
3871         }
3872
3873         BYTE_COUNT;
3874
3875         /* 1 pad byte */
3876         CHECK_BYTE_COUNT(1);
3877         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3878         COUNT_BYTES(1);
3879
3880         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
3881         bc = 0; /* XXX */
3882
3883         END_OF_SMB
3884
3885         return offset;
3886 }
3887
3888 static int
3889 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3890 {
3891         guint8 wc;
3892         guint16 bc;
3893
3894         WORD_COUNT;
3895
3896         /* write count */
3897         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3898         offset += 2;
3899
3900         BYTE_COUNT;
3901
3902         END_OF_SMB
3903
3904         return offset;
3905 }
3906
3907 static int
3908 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3909 {
3910         guint8 wc;
3911         guint16 bc, fid;
3912         guint32 to;
3913
3914         WORD_COUNT;
3915
3916         /* fid */
3917         fid = tvb_get_letohs(tvb, offset);
3918         add_fid(tvb, pinfo, tree, offset, 2, fid);
3919         offset += 2;
3920
3921         /* offset */
3922         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3923         offset += 4;
3924
3925         /* max count */
3926         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3927         offset += 2;
3928
3929         /* min count */
3930         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3931         offset += 2;
3932
3933         /* timeout */
3934         to = tvb_get_letohl(tvb, offset);
3935         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3936         offset += 4;
3937
3938         /* 2 reserved bytes */
3939         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3940         offset += 2;
3941
3942         if(wc==10){
3943                 /* high offset */
3944                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3945                 offset += 4;
3946         }
3947
3948         BYTE_COUNT;
3949
3950         END_OF_SMB
3951
3952         return offset;
3953 }
3954
3955 static int
3956 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3957 {
3958         guint8 wc;
3959         guint16 bc;
3960
3961         WORD_COUNT;
3962
3963         /* units */
3964         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3965         offset += 2;
3966
3967         /* bpu */
3968         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3969         offset += 2;
3970
3971         /* block size */
3972         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3973         offset += 2;
3974
3975         /* free units */
3976         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3977         offset += 2;
3978
3979         /* 2 reserved bytes */
3980         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3981         offset += 2;
3982
3983         BYTE_COUNT;
3984
3985         END_OF_SMB
3986
3987         return offset;
3988 }
3989
3990 static int
3991 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3992 {
3993         guint8 wc;
3994         guint16 bc, fid;
3995
3996         WORD_COUNT;
3997
3998         /* fid */
3999         fid = tvb_get_letohs(tvb, offset);
4000         add_fid(tvb, pinfo, tree, offset, 2, fid);
4001         offset += 2;
4002
4003         /* offset */
4004         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4005         offset += 4;
4006
4007         /* max count */
4008         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4009         offset += 2;
4010
4011         /* min count */
4012         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4013         offset += 2;
4014
4015         /* 6 reserved bytes */
4016         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
4017         offset += 6;
4018
4019         BYTE_COUNT;
4020
4021         END_OF_SMB
4022
4023         return offset;
4024 }
4025
4026 static int
4027 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4028 {
4029         guint16 datalen=0, bc;
4030         guint8 wc;
4031
4032         WORD_COUNT;
4033
4034         /* offset */
4035         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4036         offset += 4;
4037
4038         /* count */
4039         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4040         offset += 2;
4041
4042         /* 2 reserved bytes */
4043         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4044         offset += 2;
4045
4046         /* data compaction mode */
4047         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4048         offset += 2;
4049
4050         /* 2 reserved bytes */
4051         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4052         offset += 2;
4053
4054         /* data len */
4055         datalen = tvb_get_letohs(tvb, offset);
4056         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4057         offset += 2;
4058
4059         /* data offset */
4060         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4061         offset += 2;
4062
4063         BYTE_COUNT;
4064
4065         /* file data */
4066         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4067         bc = 0;
4068
4069         END_OF_SMB
4070
4071         return offset;
4072 }
4073
4074
4075 static const true_false_string tfs_write_mode_write_through = {
4076         "WRITE THROUGH requested",
4077         "Write through not requested"
4078 };
4079 static const true_false_string tfs_write_mode_return_remaining = {
4080         "RETURN REMAINING (pipe/dev) requested",
4081         "DON'T return remaining (pipe/dev)"
4082 };
4083 static const true_false_string tfs_write_mode_raw = {
4084         "Use WriteRawNamedPipe (pipe)",
4085         "DON'T use WriteRawNamedPipe (pipe)"
4086 };
4087 static const true_false_string tfs_write_mode_message_start = {
4088         "This is the START of a MESSAGE (pipe)",
4089         "This is NOT the start of a message (pipe)"
4090 };
4091 static const true_false_string tfs_write_mode_connectionless = {
4092         "CONNECTIONLESS mode requested",
4093         "Connectionless mode NOT requested"
4094 };
4095
4096 #define WRITE_MODE_CONNECTIONLESS       0x0080
4097 #define WRITE_MODE_MESSAGE_START        0x0008
4098 #define WRITE_MODE_RAW                  0x0004
4099 #define WRITE_MODE_RETURN_REMAINING     0x0002
4100 #define WRITE_MODE_WRITE_THROUGH        0x0001
4101
4102 static int
4103 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4104 {
4105         guint16 mask;
4106         proto_item *item = NULL;
4107         proto_tree *tree = NULL;
4108
4109         mask = tvb_get_letohs(tvb, offset);
4110
4111         if(parent_tree){
4112                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4113                         "Write Mode: 0x%04x", mask);
4114                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
4115         }
4116
4117         if(bm&WRITE_MODE_CONNECTIONLESS){
4118                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
4119                         tvb, offset, 2, mask);
4120         }
4121         if(bm&WRITE_MODE_MESSAGE_START){
4122                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
4123                         tvb, offset, 2, mask);
4124         }
4125         if(bm&WRITE_MODE_RAW){
4126                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
4127                         tvb, offset, 2, mask);
4128         }
4129         if(bm&WRITE_MODE_RETURN_REMAINING){
4130                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
4131                         tvb, offset, 2, mask);
4132         }
4133         if(bm&WRITE_MODE_WRITE_THROUGH){
4134                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4135                         tvb, offset, 2, mask);
4136         }
4137
4138         offset += 2;
4139         return offset;
4140 }
4141
4142 static int
4143 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4144 {
4145         guint32 to;
4146         guint16 datalen=0, bc, fid;
4147         guint8 wc;
4148
4149         WORD_COUNT;
4150
4151         /* fid */
4152         fid = tvb_get_letohs(tvb, offset);
4153         add_fid(tvb, pinfo, tree, offset, 2, fid);
4154         offset += 2;
4155
4156         /* total data length */
4157         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4158         offset += 2;
4159
4160         /* 2 reserved bytes */
4161         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4162         offset += 2;
4163
4164         /* offset */
4165         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4166         offset += 4;
4167
4168         /* timeout */
4169         to = tvb_get_letohl(tvb, offset);
4170         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4171         offset += 4;
4172
4173         /* mode */
4174         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4175
4176         /* 4 reserved bytes */
4177         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4178         offset += 4;
4179
4180         /* data len */
4181         datalen = tvb_get_letohs(tvb, offset);
4182         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4183         offset += 2;
4184
4185         /* data offset */
4186         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4187         offset += 2;
4188
4189         BYTE_COUNT;
4190
4191         /* file data */
4192         /* XXX - use the data offset to determine where the data starts? */
4193         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4194         bc = 0;
4195
4196         END_OF_SMB
4197
4198         return offset;
4199 }
4200
4201 static int
4202 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4203 {
4204         guint8 wc;
4205         guint16 bc;
4206
4207         WORD_COUNT;
4208
4209         /* remaining */
4210         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4211         offset += 2;
4212
4213         BYTE_COUNT;
4214
4215         END_OF_SMB
4216
4217         return offset;
4218 }
4219
4220 static int
4221 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4222 {
4223         guint32 to;
4224         guint16 datalen=0, bc, fid;
4225         guint8 wc;
4226
4227         WORD_COUNT;
4228
4229         /* fid */
4230         fid = tvb_get_letohs(tvb, offset);
4231         add_fid(tvb, pinfo, tree, offset, 2, fid);
4232         offset += 2;
4233
4234         /* total data length */
4235         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4236         offset += 2;
4237
4238         /* 2 reserved bytes */
4239         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4240         offset += 2;
4241
4242         /* offset */
4243         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4244         offset += 4;
4245
4246         /* timeout */
4247         to = tvb_get_letohl(tvb, offset);
4248         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4249         offset += 4;
4250
4251         /* mode */
4252         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
4253
4254         /* request mask */
4255         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
4256         offset += 4;
4257
4258         /* data len */
4259         datalen = tvb_get_letohs(tvb, offset);
4260         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4261         offset += 2;
4262
4263         /* data offset */
4264         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4265         offset += 2;
4266
4267         BYTE_COUNT;
4268
4269         /* file data */
4270         /* XXX - use the data offset to determine where the data starts? */
4271         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4272         bc = 0;
4273
4274         END_OF_SMB
4275
4276         return offset;
4277 }
4278
4279 static int
4280 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4281 {
4282         guint8 wc;
4283         guint16 bc;
4284
4285         WORD_COUNT;
4286
4287         /* response mask */
4288         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
4289         offset += 4;
4290
4291         BYTE_COUNT;
4292
4293         END_OF_SMB
4294
4295         return offset;
4296 }
4297
4298 static int
4299 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4300 {
4301         guint8 wc;
4302         guint16 bc;
4303
4304         WORD_COUNT;
4305
4306         /* sid */
4307         proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
4308         offset += 2;
4309
4310         BYTE_COUNT;
4311
4312         END_OF_SMB
4313
4314         return offset;
4315 }
4316
4317 static int
4318 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
4319     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4320     gboolean has_find_id)
4321 {
4322         proto_item *item = NULL;
4323         proto_tree *tree = NULL;
4324         smb_info_t *si = pinfo->private_data;
4325         int fn_len;
4326         const char *fn;
4327         char fname[11+1];
4328
4329         if(parent_tree){
4330                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
4331                         "Resume Key");
4332                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
4333         }
4334
4335         /* reserved byte */
4336         CHECK_BYTE_COUNT_SUBR(1);
4337         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4338         COUNT_BYTES_SUBR(1);
4339
4340         /* file name */
4341         fn_len = 11;
4342         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4343                 TRUE, TRUE, bcp);
4344         CHECK_STRING_SUBR(fn);
4345         /* ensure that it's null-terminated */
4346         strncpy(fname, fn, 11);
4347         fname[11] = '\0';
4348         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
4349                 fname);
4350         COUNT_BYTES_SUBR(fn_len);
4351
4352         if (has_find_id) {
4353                 CHECK_BYTE_COUNT_SUBR(1);
4354                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
4355                 COUNT_BYTES_SUBR(1);
4356
4357                 /* server cookie */
4358                 CHECK_BYTE_COUNT_SUBR(4);
4359                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
4360                 COUNT_BYTES_SUBR(4);
4361         } else {
4362                 /* server cookie */
4363                 CHECK_BYTE_COUNT_SUBR(5);
4364                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
4365                 COUNT_BYTES_SUBR(5);
4366         }
4367
4368         /* client cookie */
4369         CHECK_BYTE_COUNT_SUBR(4);
4370         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
4371         COUNT_BYTES_SUBR(4);
4372
4373         *trunc = FALSE;
4374         return offset;
4375 }
4376
4377 static int
4378 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
4379     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4380     gboolean has_find_id)
4381 {
4382         proto_item *item = NULL;
4383         proto_tree *tree = NULL;
4384         smb_info_t *si = pinfo->private_data;
4385         int fn_len;
4386         const char *fn;
4387         char fname[13+1];
4388
4389         if(parent_tree){
4390                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
4391                         "Directory Information");
4392                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
4393         }
4394
4395         /* resume key */
4396         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
4397             trunc, has_find_id);
4398         if (*trunc)
4399                 return offset;
4400
4401         /* File Attributes */
4402         CHECK_BYTE_COUNT_SUBR(1);
4403         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
4404         *bcp -= 1;
4405
4406         /* last write time */
4407         CHECK_BYTE_COUNT_SUBR(4);
4408         offset = dissect_smb_datetime(tvb, tree, offset,
4409                 hf_smb_last_write_time,
4410                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
4411                 TRUE);
4412         *bcp -= 4;
4413
4414         /* File Size */
4415         CHECK_BYTE_COUNT_SUBR(4);
4416         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4417         COUNT_BYTES_SUBR(4);
4418
4419         /* file name */
4420         fn_len = 13;
4421         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4422                 TRUE, TRUE, bcp);
4423         CHECK_STRING_SUBR(fn);
4424         /* ensure that it's null-terminated */
4425         strncpy(fname, fn, 13);
4426         fname[13] = '\0';
4427         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4428                 fname);
4429         COUNT_BYTES_SUBR(fn_len);
4430
4431         *trunc = FALSE;
4432         return offset;
4433 }
4434
4435
4436 static int
4437 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
4438     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4439     gboolean has_find_id)
4440 {
4441         smb_info_t *si = pinfo->private_data;
4442         int fn_len;
4443         const char *fn;
4444         guint16 rkl;
4445         guint8 wc;
4446         guint16 bc;
4447         gboolean trunc;
4448
4449         WORD_COUNT;
4450
4451         /* max count */
4452         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4453         offset += 2;
4454
4455         /* Search Attributes */
4456         offset = dissect_search_attributes(tvb, tree, offset);
4457
4458         BYTE_COUNT;
4459
4460         /* buffer format */
4461         CHECK_BYTE_COUNT(1);
4462         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4463         COUNT_BYTES(1);
4464
4465         /* file name */
4466         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4467                 TRUE, FALSE, &bc);
4468         if (fn == NULL)
4469                 goto endofcommand;
4470         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4471                 fn);
4472         COUNT_BYTES(fn_len);
4473
4474         if (check_col(pinfo->cinfo, COL_INFO)) {
4475                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", fn);
4476         }
4477
4478         /* buffer format */
4479         CHECK_BYTE_COUNT(1);
4480         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4481         COUNT_BYTES(1);
4482
4483         /* resume key length */
4484         CHECK_BYTE_COUNT(2);
4485         rkl = tvb_get_letohs(tvb, offset);
4486         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
4487         COUNT_BYTES(2);
4488
4489         /* resume key */
4490         if(rkl){
4491                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
4492                     &bc, &trunc, has_find_id);
4493                 if (trunc)
4494                         goto endofcommand;
4495         }
4496
4497         END_OF_SMB
4498
4499         return offset;
4500 }
4501
4502 static int
4503 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4504     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4505 {
4506         return dissect_search_find_request(tvb, pinfo, tree, offset,
4507             smb_tree, FALSE);
4508 }
4509
4510 static int
4511 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4512     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4513 {
4514         return dissect_search_find_request(tvb, pinfo, tree, offset,
4515             smb_tree, TRUE);
4516 }
4517
4518 static int
4519 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4520     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4521 {
4522         return dissect_search_find_request(tvb, pinfo, tree, offset,
4523             smb_tree, TRUE);
4524 }
4525
4526 static int
4527 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4528     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4529     gboolean has_find_id)
4530 {
4531         guint16 count=0;
4532         guint8 wc;
4533         guint16 bc;
4534         gboolean trunc;
4535
4536         WORD_COUNT;
4537
4538         /* count */
4539         count = tvb_get_letohs(tvb, offset);
4540         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
4541         offset += 2;
4542
4543         BYTE_COUNT;
4544
4545         /* buffer format */
4546         CHECK_BYTE_COUNT(1);
4547         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4548         COUNT_BYTES(1);
4549
4550         /* data len */
4551         CHECK_BYTE_COUNT(2);
4552         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4553         COUNT_BYTES(2);
4554
4555         while(count--){
4556                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
4557                     &bc, &trunc, has_find_id);
4558                 if (trunc)
4559                         goto endofcommand;
4560         }
4561
4562         END_OF_SMB
4563
4564         return offset;
4565 }
4566
4567 static int
4568 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4569 {
4570         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4571             FALSE);
4572 }
4573
4574 static int
4575 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4576 {
4577         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4578             TRUE);
4579 }
4580
4581 static int
4582 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4583     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4584 {
4585         guint8 wc;
4586         guint16 bc;
4587         guint16 data_len;
4588
4589         WORD_COUNT;
4590
4591         /* reserved */
4592         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4593         offset += 2;
4594
4595         BYTE_COUNT;
4596
4597         /* buffer format */
4598         CHECK_BYTE_COUNT(1);
4599         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4600         COUNT_BYTES(1);
4601
4602         /* data len */
4603         CHECK_BYTE_COUNT(2);
4604         data_len = tvb_get_ntohs(tvb, offset);
4605         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
4606         COUNT_BYTES(2);
4607
4608         if (data_len != 0) {
4609                 CHECK_BYTE_COUNT(data_len);
4610                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
4611                     data_len, TRUE);
4612                 COUNT_BYTES(data_len);
4613         }
4614
4615         END_OF_SMB
4616
4617         return offset;
4618 }
4619
4620 static const value_string locking_ol_vals[] = {
4621         {0,     "Client is not holding oplock on this file"},
4622         {1,     "Level 2 oplock currently held by client"},
4623         {0, NULL}
4624 };
4625
4626 static const true_false_string tfs_lock_type_large = {
4627         "Large file locking format requested",
4628         "Large file locking format not requested"
4629 };
4630 static const true_false_string tfs_lock_type_cancel = {
4631         "Cancel outstanding lock request",
4632         "Don't cancel outstanding lock request"
4633 };
4634 static const true_false_string tfs_lock_type_change = {
4635         "Change lock type",
4636         "Don't change lock type"
4637 };
4638 static const true_false_string tfs_lock_type_oplock = {
4639         "This is an oplock break notification/response",
4640         "This is not an oplock break notification/response"
4641 };
4642 static const true_false_string tfs_lock_type_shared = {
4643         "This is a shared lock",
4644         "This is an exclusive lock"
4645 };
4646 static int
4647 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4648 {
4649         guint8  wc, cmd=0xff, lt=0;
4650         guint16 andxoffset=0, un=0, ln=0, bc, fid;
4651         guint32 to;
4652         proto_item *litem = NULL;
4653         proto_tree *ltree = NULL;
4654         proto_item *it = NULL;
4655         proto_tree *tr = NULL;
4656         int old_offset = offset;
4657
4658         WORD_COUNT;
4659
4660         /* next smb command */
4661         cmd = tvb_get_guint8(tvb, offset);
4662         if(cmd!=0xff){
4663                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4664         } else {
4665                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
4666         }
4667         offset += 1;
4668
4669         /* reserved byte */
4670         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4671         offset += 1;
4672
4673         /* andxoffset */
4674         andxoffset = tvb_get_letohs(tvb, offset);
4675         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4676         offset += 2;
4677
4678         /* fid */
4679         fid = tvb_get_letohs(tvb, offset);
4680         add_fid(tvb, pinfo, tree, offset, 2, fid);
4681         offset += 2;
4682
4683         /* lock type */
4684         lt = tvb_get_guint8(tvb, offset);
4685         if(tree){
4686                 litem = proto_tree_add_text(tree, tvb, offset, 1,
4687                         "Lock Type: 0x%02x", lt);
4688                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
4689         }
4690         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
4691                 tvb, offset, 1, lt);
4692         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
4693                 tvb, offset, 1, lt);
4694         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
4695                 tvb, offset, 1, lt);
4696         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
4697                 tvb, offset, 1, lt);
4698         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
4699                 tvb, offset, 1, lt);
4700         offset += 1;
4701
4702         /* oplock level */
4703         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
4704         offset += 1;
4705
4706         /* timeout */
4707         to = tvb_get_letohl(tvb, offset);
4708         if (to == 0)
4709                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
4710         else if (to == 0xffffffff)
4711                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
4712         else
4713                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4714         offset += 4;
4715
4716         /* number of unlocks */
4717         un = tvb_get_letohs(tvb, offset);
4718         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
4719         offset += 2;
4720
4721         /* number of locks */
4722         ln = tvb_get_letohs(tvb, offset);
4723         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
4724         offset += 2;
4725
4726         BYTE_COUNT;
4727
4728         /* unlocks */
4729         if(un){
4730                 old_offset = offset;
4731
4732                 it = proto_tree_add_text(tree, tvb, offset, -1,
4733                         "Unlocks");
4734                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
4735                 while(un--){
4736                         proto_item *litem = NULL;
4737                         proto_tree *ltree = NULL;
4738                         if(lt&0x10){
4739                                 char buf[8];
4740                                 guint32 val;
4741
4742                                 /* large lock format */
4743                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4744                                         "Unlock");
4745                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4746
4747                                 /* PID */
4748                                 CHECK_BYTE_COUNT(2);
4749                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4750                                 COUNT_BYTES(2);
4751
4752                                 /* 2 reserved bytes */
4753                                 CHECK_BYTE_COUNT(2);
4754                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4755                                 COUNT_BYTES(2);
4756
4757                                 /* offset */
4758                                 CHECK_BYTE_COUNT(8);
4759                                 val=tvb_get_letohl(tvb, offset);
4760                                 buf[3]=(val>>24)&0xff;
4761                                 buf[2]=(val>>16)&0xff;
4762                                 buf[1]=(val>> 8)&0xff;
4763                                 buf[0]=(val    )&0xff;
4764                                 val=tvb_get_letohl(tvb, offset+4);
4765                                 buf[7]=(val>>24)&0xff;
4766                                 buf[6]=(val>>16)&0xff;
4767                                 buf[5]=(val>> 8)&0xff;
4768                                 buf[4]=(val    )&0xff;
4769                                 proto_tree_add_string(ltree, hf_smb_lock_long_offset, tvb, offset, 8, u64toa(buf));
4770                                 COUNT_BYTES(8);
4771
4772                                 /* length */
4773                                 CHECK_BYTE_COUNT(8);
4774                                 val=tvb_get_letohl(tvb, offset);
4775                                 buf[3]=(val>>24)&0xff;
4776                                 buf[2]=(val>>16)&0xff;
4777                                 buf[1]=(val>> 8)&0xff;
4778                                 buf[0]=(val    )&0xff;
4779                                 val=tvb_get_letohl(tvb, offset+4);
4780                                 buf[7]=(val>>24)&0xff;
4781                                 buf[6]=(val>>16)&0xff;
4782                                 buf[5]=(val>> 8)&0xff;
4783                                 buf[4]=(val    )&0xff;
4784                                 proto_tree_add_string(ltree, hf_smb_lock_long_length, tvb, offset, 8, u64toa(buf));
4785                                 COUNT_BYTES(8);
4786                         } else {
4787                                 /* normal lock format */
4788                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4789                                         "Unlock");
4790                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4791
4792                                 /* PID */
4793                                 CHECK_BYTE_COUNT(2);
4794                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4795                                 COUNT_BYTES(2);
4796
4797                                 /* offset */
4798                                 CHECK_BYTE_COUNT(4);
4799                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4800                                 COUNT_BYTES(4);
4801
4802                                 /* lock count */
4803                                 CHECK_BYTE_COUNT(4);
4804                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4805                                 COUNT_BYTES(4);
4806                         }
4807                 }
4808                 proto_item_set_len(it, offset-old_offset);
4809                 it = NULL;
4810         }
4811
4812         /* locks */
4813         if(ln){
4814                 old_offset = offset;
4815
4816                 it = proto_tree_add_text(tree, tvb, offset, -1,
4817                         "Locks");
4818                 tr = proto_item_add_subtree(it, ett_smb_locks);
4819                 while(ln--){
4820                         proto_item *litem = NULL;
4821                         proto_tree *ltree = NULL;
4822                         if(lt&0x10){
4823                                 char buf[8];
4824                                 guint32 val;
4825
4826                                 /* large lock format */
4827                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4828                                         "Lock");
4829                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
4830
4831                                 /* PID */
4832                                 CHECK_BYTE_COUNT(2);
4833                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4834                                 COUNT_BYTES(2);
4835
4836                                 /* 2 reserved bytes */
4837                                 CHECK_BYTE_COUNT(2);
4838                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4839                                 COUNT_BYTES(2);
4840
4841                                 /* offset */
4842                                 CHECK_BYTE_COUNT(8);
4843                                 val=tvb_get_letohl(tvb, offset);
4844                                 buf[3]=(val    )&0xff;
4845                                 buf[2]=(val>> 8)&0xff;
4846                                 buf[1]=(val>>16)&0xff;
4847                                 buf[0]=(val>>24)&0xff;
4848                                 val=tvb_get_letohl(tvb, offset+4);
4849                                 buf[7]=(val    )&0xff;
4850                                 buf[6]=(val>> 8)&0xff;
4851                                 buf[5]=(val>>16)&0xff;
4852                                 buf[4]=(val>>24)&0xff;
4853                                 proto_tree_add_string(ltree, hf_smb_lock_long_offset, tvb, offset, 8, u64toa(buf));
4854                                 COUNT_BYTES(8);
4855
4856                                 /* length */
4857                                 CHECK_BYTE_COUNT(8);
4858                                 val=tvb_get_letohl(tvb, offset);
4859                                 buf[3]=(val    )&0xff;
4860                                 buf[2]=(val>> 8)&0xff;
4861                                 buf[1]=(val>>16)&0xff;
4862                                 buf[0]=(val>>24)&0xff;
4863                                 val=tvb_get_letohl(tvb, offset+4);
4864                                 buf[7]=(val    )&0xff;
4865                                 buf[6]=(val>> 8)&0xff;
4866                                 buf[5]=(val>>16)&0xff;
4867                                 buf[4]=(val>>24)&0xff;
4868                                 proto_tree_add_string(ltree, hf_smb_lock_long_length, tvb, offset, 8, u64toa(buf));
4869                                 COUNT_BYTES(8);
4870                         } else {
4871                                 /* normal lock format */
4872                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4873                                         "Unlock");
4874                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4875
4876                                 /* PID */
4877                                 CHECK_BYTE_COUNT(2);
4878                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4879                                 COUNT_BYTES(2);
4880
4881                                 /* offset */
4882                                 CHECK_BYTE_COUNT(4);
4883                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4884                                 COUNT_BYTES(4);
4885
4886                                 /* lock count */
4887                                 CHECK_BYTE_COUNT(4);
4888                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4889                                 COUNT_BYTES(4);
4890                         }
4891                 }
4892                 proto_item_set_len(it, offset-old_offset);
4893                 it = NULL;
4894         }
4895
4896         END_OF_SMB
4897
4898         if (it != NULL) {
4899                 /*
4900                  * We ran out of byte count in the middle of dissecting
4901                  * the locks or the unlocks; set the site of the item
4902                  * we were dissecting.
4903                  */
4904                 proto_item_set_len(it, offset-old_offset);
4905         }
4906
4907         /* call AndXCommand (if there are any) */
4908         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4909
4910         return offset;
4911 }
4912
4913 static int
4914 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4915 {
4916         guint8  wc, cmd=0xff;
4917         guint16 andxoffset=0;
4918         guint16 bc;
4919
4920         WORD_COUNT;
4921
4922         /* next smb command */
4923         cmd = tvb_get_guint8(tvb, offset);
4924         if(cmd!=0xff){
4925                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4926         } else {
4927                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
4928         }
4929         offset += 1;
4930
4931         /* reserved byte */
4932         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4933         offset += 1;
4934
4935         /* andxoffset */
4936         andxoffset = tvb_get_letohs(tvb, offset);
4937         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4938         offset += 2;
4939
4940         BYTE_COUNT;
4941
4942         END_OF_SMB
4943
4944         /* call AndXCommand (if there are any) */
4945         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4946
4947         return offset;
4948 }
4949
4950
4951 static const value_string oa_open_vals[] = {
4952         { 0,            "No action taken?"},
4953         { 1,            "The file existed and was opened"},
4954         { 2,            "The file did not exist but was created"},
4955         { 3,            "The file existed and was truncated"},
4956         { 0x8001,       "The file existed and was opened, and an OpLock was granted"}, 
4957         { 0x8002,       "The file did not exist but was created, and an OpLock was granted"},
4958         { 0x8002,       "The file existed and was truncated, and an OpLock was granted"},
4959         {0,     NULL}
4960 };
4961 static const true_false_string tfs_oa_lock = {
4962         "File is currently opened only by this user",
4963         "File is opened by another user (or mode not supported by server)"
4964 };
4965 static int
4966 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
4967 {
4968         guint16 mask;
4969         proto_item *item = NULL;
4970         proto_tree *tree = NULL;
4971
4972         mask = tvb_get_letohs(tvb, offset);
4973
4974         if(parent_tree){
4975                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4976                         "Action: 0x%04x", mask);
4977                 tree = proto_item_add_subtree(item, ett_smb_open_action);
4978         }
4979
4980         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
4981                 tvb, offset, 2, mask);
4982         proto_tree_add_uint(tree, hf_smb_open_action_open,
4983                 tvb, offset, 2, mask);
4984
4985         offset += 2;
4986
4987         return offset;
4988 }
4989
4990 static const true_false_string tfs_open_flags_add_info = {
4991         "Additional information requested",
4992         "Additional information not requested"
4993 };
4994 static const true_false_string tfs_open_flags_ex_oplock = {
4995         "Exclusive oplock requested",
4996         "Exclusive oplock not requested"
4997 };
4998 static const true_false_string tfs_open_flags_batch_oplock = {
4999         "Batch oplock requested",
5000         "Batch oplock not requested"
5001 };
5002 static const true_false_string tfs_open_flags_ealen = {
5003         "Total length of EAs requested",
5004         "Total length of EAs not requested"
5005 };
5006 static int
5007 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
5008 {
5009         guint16 mask;
5010         proto_item *item = NULL;
5011         proto_tree *tree = NULL;
5012
5013         mask = tvb_get_letohs(tvb, offset);
5014
5015         if(parent_tree){
5016                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5017                         "Flags: 0x%04x", mask);
5018                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
5019         }
5020
5021         if(bm&0x0001){
5022                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
5023                         tvb, offset, 2, mask);
5024         }
5025         if(bm&0x0002){
5026                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
5027                         tvb, offset, 2, mask);
5028         }
5029         if(bm&0x0004){
5030                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
5031                         tvb, offset, 2, mask);
5032         }
5033         if(bm&0x0008){
5034                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
5035                         tvb, offset, 2, mask);
5036         }
5037
5038         offset += 2;
5039
5040         return offset;
5041 }
5042
5043 static const value_string filetype_vals[] = {
5044         { 0,            "Disk file or directory"},
5045         { 1,            "Named pipe in byte mode"},
5046         { 2,            "Named pipe in message mode"},
5047         { 3,            "Spooled printer"},
5048         {0, NULL}
5049 };
5050 static int
5051 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5052 {
5053         guint8  wc, cmd=0xff;
5054         guint16 andxoffset=0, bc;
5055         smb_info_t *si = pinfo->private_data;
5056         int fn_len;
5057         const char *fn;
5058
5059         WORD_COUNT;
5060
5061         /* next smb command */
5062         cmd = tvb_get_guint8(tvb, offset);
5063         if(cmd!=0xff){
5064                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5065         } else {
5066                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5067         }
5068         offset += 1;
5069
5070         /* reserved byte */
5071         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5072         offset += 1;
5073
5074         /* andxoffset */
5075         andxoffset = tvb_get_letohs(tvb, offset);
5076         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5077         offset += 2;
5078
5079         /* open flags */
5080         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
5081
5082         /* desired access */
5083         offset = dissect_access(tvb, tree, offset, "Desired");
5084
5085         /* Search Attributes */
5086         offset = dissect_search_attributes(tvb, tree, offset);
5087
5088         /* File Attributes */
5089         offset = dissect_file_attributes(tvb, tree, offset, 2);
5090
5091         /* creation time */
5092         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
5093
5094         /* open function */
5095         offset = dissect_open_function(tvb, tree, offset);
5096
5097         /* allocation size */
5098         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
5099         offset += 4;
5100
5101         /* 8 reserved bytes */
5102         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
5103         offset += 8;
5104
5105         BYTE_COUNT;
5106
5107         /* file name */
5108         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5109                 FALSE, FALSE, &bc);
5110         if (fn == NULL)
5111                 goto endofcommand;
5112         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5113                 fn);
5114         COUNT_BYTES(fn_len);
5115
5116         if (check_col(pinfo->cinfo, COL_INFO)) {
5117                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
5118         }
5119
5120         END_OF_SMB
5121
5122         /* call AndXCommand (if there are any) */
5123         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5124
5125         return offset;
5126 }
5127
5128 static const true_false_string tfs_ipc_state_nonblocking = {
5129         "Reads/writes return immediately if no data available",
5130         "Reads/writes block if no data available"
5131 };
5132 static const value_string ipc_state_endpoint_vals[] = {
5133         { 0,            "Consumer end of pipe"},
5134         { 1,            "Server end of pipe"},
5135         {0,     NULL}
5136 };
5137 static const value_string ipc_state_pipe_type_vals[] = {
5138         { 0,            "Byte stream pipe"},
5139         { 1,            "Message pipe"},
5140         {0,     NULL}
5141 };
5142 static const value_string ipc_state_read_mode_vals[] = {
5143         { 0,            "Read pipe as a byte stream"},
5144         { 1,            "Read messages from pipe"},
5145         {0,     NULL}
5146 };
5147
5148 int
5149 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
5150     gboolean setstate)
5151 {
5152         guint16 mask;
5153         proto_item *item = NULL;
5154         proto_tree *tree = NULL;
5155
5156         mask = tvb_get_letohs(tvb, offset);
5157
5158         if(parent_tree){
5159                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5160                         "IPC State: 0x%04x", mask);
5161                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
5162         }
5163
5164         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
5165                 tvb, offset, 2, mask);
5166         if (!setstate) {
5167                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
5168                         tvb, offset, 2, mask);
5169                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
5170                         tvb, offset, 2, mask);
5171         }
5172         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
5173                 tvb, offset, 2, mask);
5174         if (!setstate) {
5175                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
5176                         tvb, offset, 2, mask);
5177         }
5178
5179         offset += 2;
5180
5181         return offset;
5182 }
5183
5184 static int
5185 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5186 {
5187         guint8  wc, cmd=0xff;
5188         guint16 andxoffset=0, bc;
5189         guint16 fid;
5190
5191         WORD_COUNT;
5192
5193         /* next smb command */
5194         cmd = tvb_get_guint8(tvb, offset);
5195         if(cmd!=0xff){
5196                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5197         } else {
5198                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5199         }
5200         offset += 1;
5201
5202         /* reserved byte */
5203         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5204         offset += 1;
5205
5206         /* andxoffset */
5207         andxoffset = tvb_get_letohs(tvb, offset);
5208         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5209         offset += 2;
5210
5211         /* fid */
5212         fid = tvb_get_letohs(tvb, offset);
5213         add_fid(tvb, pinfo, tree, offset, 2, fid);
5214         offset += 2;
5215
5216         /* File Attributes */
5217         offset = dissect_file_attributes(tvb, tree, offset, 2);
5218
5219         /* last write time */
5220         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
5221
5222         /* File Size */
5223         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5224         offset += 4;
5225
5226         /* granted access */
5227         offset = dissect_access(tvb, tree, offset, "Granted");
5228
5229         /* File Type */
5230         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
5231         offset += 2;
5232
5233         /* IPC State */
5234         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
5235
5236         /* open_action */
5237         offset = dissect_open_action(tvb, tree, offset);
5238
5239         /* server fid */
5240         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
5241         offset += 4;
5242
5243         /* 2 reserved bytes */
5244         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5245         offset += 2;
5246
5247         BYTE_COUNT;
5248
5249         END_OF_SMB
5250
5251         /* call AndXCommand (if there are any) */
5252         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5253
5254         return offset;
5255 }
5256
5257 static int
5258 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5259 {
5260         guint8  wc, cmd=0xff;
5261         guint16 andxoffset=0, bc, maxcnt_low;
5262         guint32 maxcnt_high;
5263         guint32 maxcnt=0;
5264         guint32 ofs = 0;
5265         smb_info_t *si;
5266         unsigned int fid;
5267
5268         WORD_COUNT;
5269
5270         /* next smb command */
5271         cmd = tvb_get_guint8(tvb, offset);
5272         if(cmd!=0xff){
5273                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5274         } else {
5275                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5276         }
5277         offset += 1;
5278
5279         /* reserved byte */
5280         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5281         offset += 1;
5282
5283         /* andxoffset */
5284         andxoffset = tvb_get_letohs(tvb, offset);
5285         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5286         offset += 2;
5287
5288         /* fid */
5289         fid = tvb_get_letohs(tvb, offset);
5290         add_fid(tvb, pinfo, tree, offset, 2, fid);
5291         offset += 2;
5292         if (!pinfo->fd->flags.visited) {
5293                 /* remember the FID for the processing of the response */
5294                 si = (smb_info_t *)pinfo->private_data;
5295                 si->sip->extra_info=(void *)fid;
5296         }
5297
5298         /* offset */
5299         ofs = tvb_get_letohl(tvb, offset);
5300         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5301         offset += 4;
5302
5303         /* max count low */
5304         maxcnt_low = tvb_get_letohs(tvb, offset);
5305         proto_tree_add_uint(tree, hf_smb_max_count_low, tvb, offset, 2, maxcnt_low);
5306         offset += 2;
5307
5308         /* min count */
5309         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
5310         offset += 2;
5311
5312         /*
5313          * max count high
5314          *
5315          * XXX - we should really only do this in case we have seen
5316          * LARGE FILE being negotiated.  Unfortunately, we might not
5317          * have seen the negotiation phase in the capture....
5318          *
5319          * XXX - this is shown as a ULONG in the SNIA SMB spec, i.e.
5320          * it's 32 bits, but the description says "High 16 bits of
5321          * MaxCount if CAP_LARGE_READX".
5322          *
5323          * The SMB File Sharing Protocol Extensions Version 2.0,
5324          * Document Version 3.3 spec doesn't speak of an extra 16
5325          * bits in max count, but it does show a 32-bit timeout
5326          * after the min count field.
5327          *
5328          * Perhaps the 32-bit timeout field was hijacked as a 16-bit
5329          * high count and a 16-bit reserved field.
5330          *
5331          * We fetch and display it as 32 bits.
5332          * 
5333          * XXX if maxcount high is 0xFFFFFFFF we assume it is just padding
5334          * bytes and we just ignore it.
5335          */
5336         maxcnt_high = tvb_get_letohl(tvb, offset);
5337         if(maxcnt_high==0xffffffff){
5338                 maxcnt_high=0;
5339         } else {
5340                 proto_tree_add_uint(tree, hf_smb_max_count_high, tvb, offset, 4, maxcnt_high);
5341         }
5342
5343         offset += 4;
5344
5345         maxcnt=maxcnt_high;
5346         maxcnt=(maxcnt<<16)|maxcnt_low;
5347
5348         if (check_col(pinfo->cinfo, COL_INFO))
5349                 col_append_fstr(pinfo->cinfo, COL_INFO,
5350                                 ", %u byte%s at offset %u", maxcnt,
5351                                 (maxcnt == 1) ? "" : "s", ofs);
5352
5353         /* remaining */
5354         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5355         offset += 2;
5356
5357         if(wc==12){
5358                 /* high offset */
5359                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5360                 offset += 4;
5361         }
5362
5363         BYTE_COUNT;
5364
5365         END_OF_SMB
5366
5367         /* call AndXCommand (if there are any) */
5368         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5369
5370         return offset;
5371 }
5372
5373 static int
5374 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5375 {
5376         guint8  wc, cmd=0xff;
5377         guint16 andxoffset=0, bc, datalen_low, datalen_high, dataoffset=0;
5378         guint32 datalen=0;
5379         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5380         int fid=0;
5381
5382         WORD_COUNT;
5383
5384         /* next smb command */
5385         cmd = tvb_get_guint8(tvb, offset);
5386         if(cmd!=0xff){
5387                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5388         } else {
5389                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5390         }
5391         offset += 1;
5392
5393         /* reserved byte */
5394         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5395         offset += 1;
5396
5397         /* andxoffset */
5398         andxoffset = tvb_get_letohs(tvb, offset);
5399         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5400         offset += 2;
5401
5402         /* If we have seen the request, then print which FID this refers to */
5403         /* first check if we have seen the request */
5404         if(si->sip != NULL && si->sip->frame_req>0){
5405                 fid=(int)si->sip->extra_info;
5406                 add_fid(tvb, pinfo, tree, 0, 0, fid);
5407         }
5408
5409         /* remaining */
5410         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5411         offset += 2;
5412
5413         /* data compaction mode */
5414         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
5415         offset += 2;
5416
5417         /* 2 reserved bytes */
5418         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5419         offset += 2;
5420
5421         /* data len low */
5422         datalen_low = tvb_get_letohs(tvb, offset);
5423         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
5424         offset += 2;
5425
5426         /* data offset */
5427         dataoffset=tvb_get_letohs(tvb, offset);
5428         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5429         offset += 2;
5430
5431         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5432         /* data length high */
5433         datalen_high = tvb_get_letohs(tvb, offset);
5434         proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
5435         offset += 2;
5436
5437         datalen=datalen_high;
5438         datalen=(datalen<<16)|datalen_low;
5439
5440
5441         if (check_col(pinfo->cinfo, COL_INFO))
5442                 col_append_fstr(pinfo->cinfo, COL_INFO,
5443                                 ", %u byte%s", datalen,
5444                                 (datalen == 1) ? "" : "s");
5445
5446
5447         /* 8 reserved bytes */
5448         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
5449         offset += 8;
5450
5451         BYTE_COUNT;
5452
5453         /* file data, might be DCERPC on a pipe */
5454         if(bc){
5455                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5456                     top_tree, offset, bc, datalen, 0, fid);
5457                 bc = 0;
5458         }
5459
5460         END_OF_SMB
5461
5462         /* call AndXCommand (if there are any) */
5463         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5464
5465         return offset;
5466 }
5467
5468 static int
5469 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5470 {
5471         guint32 ofs=0;
5472         guint8  wc, cmd=0xff;
5473         guint16 andxoffset=0, bc, dataoffset=0, datalen_low, datalen_high;
5474         guint32 datalen=0;
5475         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5476         unsigned int fid=0;
5477         guint16 mode = 0;
5478
5479         WORD_COUNT;
5480
5481         /* next smb command */
5482         cmd = tvb_get_guint8(tvb, offset);
5483         if(cmd!=0xff){
5484                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5485         } else {
5486                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5487         }
5488         offset += 1;
5489
5490         /* reserved byte */
5491         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5492         offset += 1;
5493
5494         /* andxoffset */
5495         andxoffset = tvb_get_letohs(tvb, offset);
5496         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5497         offset += 2;
5498
5499         /* fid */
5500         fid = tvb_get_letohs(tvb, offset);
5501         add_fid(tvb, pinfo, tree, offset, 2, fid);
5502         offset += 2;
5503         if (!pinfo->fd->flags.visited) {
5504                 /* remember the FID for the processing of the response */
5505                 si->sip->extra_info=(void *)fid;
5506         }
5507
5508         /* offset */
5509         ofs = tvb_get_letohl(tvb, offset);
5510         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5511         offset += 4;
5512
5513         /* reserved */
5514         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5515         offset += 4;
5516
5517         /* mode */
5518         mode = tvb_get_letohs(tvb, offset);
5519         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
5520
5521         /* remaining */
5522         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5523         offset += 2;
5524
5525         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5526         /* data length high */
5527         datalen_high = tvb_get_letohs(tvb, offset);
5528         proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
5529         offset += 2;
5530
5531         /* data len low */
5532         datalen_low = tvb_get_letohs(tvb, offset);
5533         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
5534         offset += 2;
5535
5536         datalen=datalen_high;
5537         datalen=(datalen<<16)|datalen_low;
5538
5539         /* data offset */
5540         dataoffset=tvb_get_letohs(tvb, offset);
5541         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5542         offset += 2;
5543
5544         /* FIXME: handle Large (48-bit) byte/offset to COL_INFO */
5545         if (check_col(pinfo->cinfo, COL_INFO))
5546                 col_append_fstr(pinfo->cinfo, COL_INFO,
5547                                 ", %u byte%s at offset %u", datalen,
5548                                 (datalen == 1) ? "" : "s", ofs);
5549
5550         if(wc==14){
5551                 /* high offset */
5552                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5553                 offset += 4;
5554         }
5555
5556         BYTE_COUNT;
5557
5558         /* if both the MessageStart and the  WriteRawNamedPipe flags are set
5559            the first two bytes of the payload is the length of the data
5560            also this tells us that this is indeed the IPC$ share
5561            (if we didnt already know that 
5562         */
5563         if((mode&(WRITE_MODE_MESSAGE_START|WRITE_MODE_RAW))==(WRITE_MODE_MESSAGE_START|WRITE_MODE_RAW)){
5564                 proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, TRUE);
5565                 offset += 2;
5566                 dataoffset += 2;
5567                 bc -= 2;
5568                 datalen -= 2;
5569                 if(si->sip){
5570                         si->sip->flags|=SMB_SIF_TID_IS_IPC;
5571                 }
5572         }
5573
5574         /* file data, might be DCERPC on a pipe */
5575         if (bc != 0) {
5576                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5577                     top_tree, offset, bc, datalen, 0, fid);
5578                 bc = 0;
5579         }
5580
5581         END_OF_SMB
5582
5583         /* call AndXCommand (if there are any) */
5584         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5585
5586         return offset;
5587 }
5588
5589 static int
5590 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5591 {
5592         guint8  wc, cmd=0xff;
5593         guint16 andxoffset=0, bc, count_low, count_high;
5594         guint32 count=0;
5595         smb_info_t *si;
5596
5597         WORD_COUNT;
5598
5599         /* next smb command */
5600         cmd = tvb_get_guint8(tvb, offset);
5601         if(cmd!=0xff){
5602                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5603         } else {
5604                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5605         }
5606         offset += 1;
5607
5608         /* reserved byte */
5609         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5610         offset += 1;
5611
5612         /* andxoffset */
5613         andxoffset = tvb_get_letohs(tvb, offset);
5614         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5615         offset += 2;
5616
5617         /* If we have seen the request, then print which FID this refers to */
5618         si = (smb_info_t *)pinfo->private_data;
5619         /* first check if we have seen the request */
5620         if(si->sip != NULL && si->sip->frame_req>0){
5621                 add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
5622         }
5623
5624         /* write count low */
5625         count_low = tvb_get_letohs(tvb, offset);
5626         proto_tree_add_uint(tree, hf_smb_count_low, tvb, offset, 2, count_low);
5627         offset += 2;
5628
5629         /* remaining */
5630         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5631         offset += 2;
5632
5633         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5634         /* write count high */
5635         count_high = tvb_get_letohs(tvb, offset);
5636         proto_tree_add_uint(tree, hf_smb_count_high, tvb, offset, 2, count_high);
5637         offset += 2;
5638
5639         count=count_high;
5640         count=(count<<16)|count_low;
5641
5642         if (check_col(pinfo->cinfo, COL_INFO))
5643                 col_append_fstr(pinfo->cinfo, COL_INFO,
5644                                 ", %u byte%s", count,
5645                                 (count == 1) ? "" : "s");
5646
5647         /* 2 reserved bytes */
5648         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5649         offset += 2;
5650
5651         BYTE_COUNT;
5652
5653         END_OF_SMB
5654
5655         /* call AndXCommand (if there are any) */
5656         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5657
5658         return offset;
5659 }
5660
5661
5662 static const true_false_string tfs_setup_action_guest = {
5663         "Logged in as GUEST",
5664         "Not logged in as GUEST"
5665 };
5666 static int
5667 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5668 {
5669         guint16 mask;
5670         proto_item *item = NULL;
5671         proto_tree *tree = NULL;
5672
5673         mask = tvb_get_letohs(tvb, offset);
5674
5675         if(parent_tree){
5676                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5677                         "Action: 0x%04x", mask);
5678                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
5679         }
5680
5681         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
5682                 tvb, offset, 2, mask);
5683
5684         offset += 2;
5685
5686         return offset;
5687 }
5688
5689
5690 static int
5691 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5692 {
5693         guint8  wc, cmd=0xff;
5694         guint16 bc;
5695         guint16 andxoffset=0;
5696         smb_info_t *si = pinfo->private_data;
5697         int an_len;
5698         const char *an;
5699         int dn_len;
5700         const char *dn;
5701         guint16 pwlen=0;
5702         guint16 sbloblen=0;
5703         guint16 apwlen=0, upwlen=0;
5704
5705         WORD_COUNT;
5706
5707         /* next smb command */
5708         cmd = tvb_get_guint8(tvb, offset);
5709         if(cmd!=0xff){
5710                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5711         } else {
5712                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5713         }
5714         offset += 1;
5715
5716         /* reserved byte */
5717         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5718         offset += 1;
5719
5720         /* andxoffset */
5721         andxoffset = tvb_get_letohs(tvb, offset);
5722         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5723         offset += 2;
5724
5725         /* Maximum Buffer Size */
5726         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
5727         offset += 2;
5728
5729         /* Maximum Multiplex Count */
5730         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
5731         offset += 2;
5732
5733         /* VC Number */
5734         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
5735         offset += 2;
5736
5737         /* session key */
5738         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
5739         offset += 4;
5740
5741         switch (wc) {
5742         case 10:
5743                 /* password length, ASCII*/
5744                 pwlen = tvb_get_letohs(tvb, offset);
5745                 proto_tree_add_uint(tree, hf_smb_password_len,
5746                         tvb, offset, 2, pwlen);
5747                 offset += 2;
5748
5749                 /* 4 reserved bytes */
5750                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5751                 offset += 4;
5752
5753                 break;
5754
5755         case 12:
5756                 /* security blob length */
5757                 sbloblen = tvb_get_letohs(tvb, offset);
5758                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5759                 offset += 2;
5760
5761                 /* 4 reserved bytes */
5762                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5763                 offset += 4;
5764
5765                 /* capabilities */
5766                 dissect_negprot_capabilities(tvb, tree, offset);
5767                 offset += 4;
5768
5769                 break;
5770
5771         case 13:
5772                 /* password length, ANSI*/
5773                 apwlen = tvb_get_letohs(tvb, offset);
5774                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
5775                         tvb, offset, 2, apwlen);
5776                 offset += 2;
5777
5778                 /* password length, Unicode*/
5779                 upwlen = tvb_get_letohs(tvb, offset);
5780                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
5781                         tvb, offset, 2, upwlen);
5782                 offset += 2;
5783
5784                 /* 4 reserved bytes */
5785                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5786                 offset += 4;
5787
5788                 /* capabilities */
5789                 dissect_negprot_capabilities(tvb, tree, offset);
5790                 offset += 4;
5791
5792                 break;
5793         }
5794
5795         BYTE_COUNT;
5796
5797         if (wc==12) {
5798                 proto_item *blob_item;
5799
5800                 /* security blob */
5801
5802                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
5803                                                 tvb, offset, sbloblen, TRUE);
5804
5805                 /* As an optimization, because Windows is perverse,
5806                    we check to see if NTLMSSP is the first part of the 
5807                    blob, and if so, call the NTLMSSP dissector,
5808                    otherwise we call the GSS-API dissector. This is because
5809                    Windows can request RAW NTLMSSP, but will happily handle
5810                    a client that wraps NTLMSSP in SPNEGO
5811                 */
5812
5813                 if(sbloblen){
5814                         tvbuff_t *blob_tvb;
5815                         proto_tree *blob_tree;
5816
5817                         blob_tree = proto_item_add_subtree(blob_item, 
5818                                                            ett_smb_secblob);
5819                         CHECK_BYTE_COUNT(sbloblen);
5820
5821                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
5822                                                   sbloblen);
5823
5824                         if (si && si->ct && si->ct->raw_ntlmssp && 
5825                             !strncmp("NTLMSSP", 
5826                                      tvb_get_ptr(tvb, offset, 7), 7)) {
5827                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
5828                                          blob_tree);
5829
5830                         }
5831                         else {
5832                           call_dissector(gssapi_handle, blob_tvb, 
5833                                          pinfo, blob_tree);
5834                         }
5835
5836                         COUNT_BYTES(sbloblen);
5837                 }
5838
5839                 /* OS */
5840                 an = get_unicode_or_ascii_string(tvb, &offset,
5841                         si->unicode, &an_len, FALSE, FALSE, &bc);
5842                 if (an == NULL)
5843                         goto endofcommand;
5844                 proto_tree_add_string(tree, hf_smb_os, tvb,
5845                         offset, an_len, an);
5846                 COUNT_BYTES(an_len);
5847
5848                 /* LANMAN */
5849                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5850                  * padding/null string/whatever in front of this. W2K doesn't
5851                  * appear to. I suspect that's a bug that got fixed; I also
5852                  * suspect that, in practice, nobody ever looks at that field
5853                  * because the bug didn't appear to get fixed until NT 5.0....
5854                  */
5855                 an = get_unicode_or_ascii_string(tvb, &offset,
5856                         si->unicode, &an_len, FALSE, FALSE, &bc);
5857                 if (an == NULL)
5858                         goto endofcommand;
5859                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5860                         offset, an_len, an);
5861                 COUNT_BYTES(an_len);
5862
5863                 /* Primary domain */
5864                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5865                  * byte in front of this, at least if all the strings are
5866                  * ASCII and the account name is empty. Another bug?
5867                  */
5868                 dn = get_unicode_or_ascii_string(tvb, &offset,
5869                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5870                 if (dn == NULL)
5871                         goto endofcommand;
5872                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5873                         offset, dn_len, dn);
5874                 COUNT_BYTES(dn_len);
5875         } else {
5876                 switch (wc) {
5877
5878                 case 10:
5879                         if(pwlen){
5880                                 /* password, ASCII */
5881                                 CHECK_BYTE_COUNT(pwlen);
5882                                 proto_tree_add_item(tree, hf_smb_password,
5883                                         tvb, offset, pwlen, TRUE);
5884                                 COUNT_BYTES(pwlen);
5885                         }
5886
5887                         break;
5888
5889                 case 13:
5890                         if(apwlen){
5891                                 /* password, ANSI */
5892                                 CHECK_BYTE_COUNT(apwlen);
5893                                 proto_tree_add_item(tree, hf_smb_ansi_password,
5894                                         tvb, offset, apwlen, TRUE);
5895                                 COUNT_BYTES(apwlen);
5896                         }
5897
5898                         if(upwlen){
5899                                 proto_item *item;
5900
5901                                 /* password, Unicode */
5902                                 CHECK_BYTE_COUNT(upwlen);
5903                                 item = proto_tree_add_item(tree, hf_smb_unicode_password,
5904                                         tvb, offset, upwlen, TRUE);
5905
5906                                 if (upwlen > 24) {
5907                                         proto_tree *subtree;
5908
5909                                         subtree = proto_item_add_subtree(item, ett_smb_unicode_password);
5910
5911                                         dissect_ntlmv2_response(
5912                                                 tvb, subtree, offset, upwlen);
5913                                 }
5914
5915                                 COUNT_BYTES(upwlen);
5916                         }
5917
5918                         break;
5919                 }
5920
5921                 /* Account Name */
5922                 an = get_unicode_or_ascii_string(tvb, &offset,
5923                         si->unicode, &an_len, FALSE, FALSE, &bc);
5924                 if (an == NULL)
5925                         goto endofcommand;
5926                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
5927                         an);
5928                 COUNT_BYTES(an_len);
5929
5930                 /* Primary domain */
5931                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5932                  * byte in front of this, at least if all the strings are
5933                  * ASCII and the account name is empty. Another bug?
5934                  */
5935                 dn = get_unicode_or_ascii_string(tvb, &offset,
5936                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5937                 if (dn == NULL)
5938                         goto endofcommand;
5939                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5940                         offset, dn_len, dn);
5941                 COUNT_BYTES(dn_len);
5942
5943                 if (check_col(pinfo->cinfo, COL_INFO)) {
5944                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
5945
5946                         if (!dn[0] && !an[0])
5947                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5948                                                 "anonymous");
5949                         else
5950                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5951                                                 "%s\\%s", dn,an);
5952                 }
5953
5954                 /* OS */
5955                 an = get_unicode_or_ascii_string(tvb, &offset,
5956                         si->unicode, &an_len, FALSE, FALSE, &bc);
5957                 if (an == NULL)
5958                         goto endofcommand;
5959                 proto_tree_add_string(tree, hf_smb_os, tvb,
5960                         offset, an_len, an);
5961                 COUNT_BYTES(an_len);
5962
5963                 /* LANMAN */
5964                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5965                  * padding/null string/whatever in front of this. W2K doesn't
5966                  * appear to. I suspect that's a bug that got fixed; I also
5967                  * suspect that, in practice, nobody ever looks at that field
5968                  * because the bug didn't appear to get fixed until NT 5.0....
5969                  */
5970                 an = get_unicode_or_ascii_string(tvb, &offset,
5971                         si->unicode, &an_len, FALSE, FALSE, &bc);
5972                 if (an == NULL)
5973                         goto endofcommand;
5974                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5975                         offset, an_len, an);
5976                 COUNT_BYTES(an_len);
5977         }
5978
5979         END_OF_SMB
5980
5981         /* call AndXCommand (if there are any) */
5982         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5983
5984         return offset;
5985 }
5986
5987 static int
5988 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5989 {
5990         guint8  wc, cmd=0xff;
5991         guint16 andxoffset=0, bc;
5992         guint16 sbloblen=0;
5993         smb_info_t *si = pinfo->private_data;
5994         int an_len;
5995         const char *an;
5996
5997         WORD_COUNT;
5998
5999         /* next smb command */
6000         cmd = tvb_get_guint8(tvb, offset);
6001         if(cmd!=0xff){
6002                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6003         } else {
6004                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6005         }
6006         offset += 1;
6007
6008         /* reserved byte */
6009         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6010         offset += 1;
6011
6012         /* andxoffset */
6013         andxoffset = tvb_get_letohs(tvb, offset);
6014         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6015         offset += 2;
6016
6017         /* flags */
6018         offset = dissect_setup_action(tvb, tree, offset);
6019
6020         if(wc==4){
6021                 /* security blob length */
6022                 sbloblen = tvb_get_letohs(tvb, offset);
6023                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
6024                 offset += 2;
6025         }
6026
6027         BYTE_COUNT;
6028
6029         if(wc==4) {
6030                 proto_item *blob_item;
6031
6032                 /* security blob */
6033
6034                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
6035                                                 tvb, offset, sbloblen, TRUE);
6036
6037                 if(sbloblen){
6038                         tvbuff_t *blob_tvb;
6039                         proto_tree *blob_tree;
6040
6041                         blob_tree = proto_item_add_subtree(blob_item, 
6042                                                            ett_smb_secblob);
6043                         CHECK_BYTE_COUNT(sbloblen);
6044
6045                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
6046                                                     sbloblen);
6047
6048                         if (si && si->ct && si->ct->raw_ntlmssp && 
6049                             !strncmp("NTLMSSP", 
6050                                      tvb_get_ptr(tvb, offset, 7), 7)) {
6051                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
6052                                          blob_tree);
6053
6054                         }
6055                         else {
6056                           call_dissector(gssapi_handle, blob_tvb, pinfo, 
6057                                          blob_tree);
6058
6059                         }
6060
6061                         COUNT_BYTES(sbloblen);
6062                 }
6063         }
6064
6065         /* OS */
6066         an = get_unicode_or_ascii_string(tvb, &offset,
6067                 si->unicode, &an_len, FALSE, FALSE, &bc);
6068         if (an == NULL)
6069                 goto endofcommand;
6070         proto_tree_add_string(tree, hf_smb_os, tvb,
6071                 offset, an_len, an);
6072         COUNT_BYTES(an_len);
6073
6074         /* LANMAN */
6075         an = get_unicode_or_ascii_string(tvb, &offset,
6076                 si->unicode, &an_len, FALSE, FALSE, &bc);
6077         if (an == NULL)
6078                 goto endofcommand;
6079         proto_tree_add_string(tree, hf_smb_lanman, tvb,
6080                 offset, an_len, an);
6081         COUNT_BYTES(an_len);
6082
6083         if(wc==3) {
6084                 /* Primary domain */
6085                 an = get_unicode_or_ascii_string(tvb, &offset,
6086                         si->unicode, &an_len, FALSE, FALSE, &bc);
6087                 if (an == NULL)
6088                         goto endofcommand;
6089                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
6090                         offset, an_len, an);
6091                 COUNT_BYTES(an_len);
6092         }
6093
6094         END_OF_SMB
6095
6096         /* call AndXCommand (if there are any) */
6097         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6098
6099         return offset;
6100 }
6101
6102
6103 static int
6104 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6105 {
6106         guint8  wc, cmd=0xff;
6107         guint16 andxoffset=0;
6108         guint16 bc;
6109
6110         WORD_COUNT;
6111
6112         /* next smb command */
6113         cmd = tvb_get_guint8(tvb, offset);
6114         if(cmd!=0xff){
6115                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6116         } else {
6117                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6118         }
6119         offset += 1;
6120
6121         /* reserved byte */
6122         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6123         offset += 1;
6124
6125         /* andxoffset */
6126         andxoffset = tvb_get_letohs(tvb, offset);
6127         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6128         offset += 2;
6129
6130         BYTE_COUNT;
6131
6132         END_OF_SMB
6133
6134         /* call AndXCommand (if there are any) */
6135         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6136
6137         return offset;
6138 }
6139
6140
6141 static const true_false_string tfs_connect_support_search = {
6142         "Exclusive search bits supported",
6143         "Exclusive search bits not supported"
6144 };
6145 static const true_false_string tfs_connect_support_in_dfs = {
6146         "Share is in Dfs",
6147         "Share isn't in Dfs"
6148 };
6149
6150 static int
6151 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6152 {
6153         guint16 mask;
6154         proto_item *item = NULL;
6155         proto_tree *tree = NULL;
6156
6157         mask = tvb_get_letohs(tvb, offset);
6158
6159         if(parent_tree){
6160                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6161                         "Optional Support: 0x%04x", mask);
6162                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
6163         }
6164
6165         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
6166                 tvb, offset, 2, mask);
6167         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
6168                 tvb, offset, 2, mask);
6169
6170         offset += 2;
6171
6172         return offset;
6173 }
6174
6175 static const true_false_string tfs_disconnect_tid = {
6176         "DISCONNECT TID",
6177         "Do NOT disconnect TID"
6178 };
6179
6180 static int
6181 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6182 {
6183         guint16 mask;
6184         proto_item *item = NULL;
6185         proto_tree *tree = NULL;
6186
6187         mask = tvb_get_letohs(tvb, offset);
6188
6189         if(parent_tree){
6190                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6191                         "Flags: 0x%04x", mask);
6192                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
6193         }
6194
6195         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
6196                 tvb, offset, 2, mask);
6197
6198         offset += 2;
6199
6200         return offset;
6201 }
6202
6203 static int
6204 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6205 {
6206         guint8  wc, cmd=0xff;
6207         guint16 bc;
6208         guint16 andxoffset=0, pwlen=0;
6209         smb_info_t *si = pinfo->private_data;
6210         int an_len;
6211         const char *an;
6212
6213         WORD_COUNT;
6214
6215         /* next smb command */
6216         cmd = tvb_get_guint8(tvb, offset);
6217         if(cmd!=0xff){
6218                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6219         } else {
6220                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6221         }
6222         offset += 1;
6223
6224         /* reserved byte */
6225         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6226         offset += 1;
6227
6228         /* andxoffset */
6229         andxoffset = tvb_get_letohs(tvb, offset);
6230         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6231         offset += 2;
6232
6233         /* flags */
6234         offset = dissect_connect_flags(tvb, tree, offset);
6235
6236         /* password length*/
6237         pwlen = tvb_get_letohs(tvb, offset);
6238         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
6239         offset += 2;
6240
6241         BYTE_COUNT;
6242
6243         /* password */
6244         CHECK_BYTE_COUNT(pwlen);
6245         proto_tree_add_item(tree, hf_smb_password,
6246                 tvb, offset, pwlen, TRUE);
6247         COUNT_BYTES(pwlen);
6248
6249         /* Path */
6250         an = get_unicode_or_ascii_string(tvb, &offset,
6251                 si->unicode, &an_len, FALSE, FALSE, &bc);
6252         if (an == NULL)
6253                 goto endofcommand;
6254         proto_tree_add_string(tree, hf_smb_path, tvb,
6255                 offset, an_len, an);
6256         COUNT_BYTES(an_len);
6257
6258         if (check_col(pinfo->cinfo, COL_INFO)) {
6259                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
6260         }
6261
6262         /*
6263          * NOTE: the Service string is always ASCII, even if the
6264          * "strings are Unicode" bit is set in the flags2 field
6265          * of the SMB.
6266          */
6267
6268         /* Service */
6269         /* XXX - what if this runs past bc? */
6270         an_len = tvb_strsize(tvb, offset);
6271         CHECK_BYTE_COUNT(an_len);
6272         an = tvb_get_ptr(tvb, offset, an_len);
6273         proto_tree_add_string(tree, hf_smb_service, tvb,
6274                 offset, an_len, an);
6275         COUNT_BYTES(an_len);
6276
6277         END_OF_SMB
6278
6279         /* call AndXCommand (if there are any) */
6280         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6281
6282         return offset;
6283 }
6284
6285
6286 static int
6287 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6288 {
6289         guint8  wc, wleft, cmd=0xff;
6290         guint16 andxoffset=0;
6291         guint16 bc;
6292         int an_len;
6293         const char *an;
6294         smb_info_t *si = pinfo->private_data;
6295
6296         WORD_COUNT;
6297
6298         wleft = wc;     /* this is at least 1 */
6299
6300         /* next smb command */
6301         cmd = tvb_get_guint8(tvb, offset);
6302         if(cmd!=0xff){
6303                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6304         } else {
6305                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6306         }
6307         offset += 1;
6308
6309         /* reserved byte */
6310         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6311         offset += 1;
6312
6313         wleft--;
6314         if (wleft == 0)
6315                 goto bytecount;
6316
6317         /* andxoffset */
6318         andxoffset = tvb_get_letohs(tvb, offset);
6319         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6320         offset += 2;
6321         wleft--;
6322         if (wleft == 0)
6323                 goto bytecount;
6324
6325         /* flags */
6326         offset = dissect_connect_support_bits(tvb, tree, offset);
6327         wleft--;
6328
6329         /* XXX - I've seen captures where this is 7, but I have no
6330            idea how to dissect it.  I'm guessing the third word
6331            contains connect support bits, which looks plausible
6332            from the values I've seen. */
6333
6334         while (wleft != 0) {
6335                 proto_tree_add_text(tree, tvb, offset, 2,
6336                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
6337                 offset += 2;
6338                 wleft--;
6339         }
6340
6341         BYTE_COUNT;
6342
6343         /*
6344          * NOTE: even though the SNIA CIFS spec doesn't say there's
6345          * a "Service" string if there's a word count of 2, the
6346          * document at
6347          *
6348          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
6349          *
6350          * (it's in an ugly format - text intended to be sent to a
6351          * printer, with backspaces and overstrikes used for boldfacing
6352          * and underlining; UNIX "col -b" can be used to strip the
6353          * overstrikes out) says there's a "Service" string there, and
6354          * some network traffic has it.
6355          */
6356
6357         /*
6358          * NOTE: the Service string is always ASCII, even if the
6359          * "strings are Unicode" bit is set in the flags2 field
6360          * of the SMB.
6361          */
6362
6363         /* Service */
6364         /* XXX - what if this runs past bc? */
6365         an_len = tvb_strsize(tvb, offset);
6366         CHECK_BYTE_COUNT(an_len);
6367         an = tvb_get_ptr(tvb, offset, an_len);
6368         proto_tree_add_string(tree, hf_smb_service, tvb,
6369                 offset, an_len, an);
6370         COUNT_BYTES(an_len);
6371
6372         /* Now when we know the service type, store it so that we know it for later commands down
6373            this tree */
6374         if(!pinfo->fd->flags.visited){
6375                 /* Remove any previous entry for this TID */
6376                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
6377                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
6378                 }
6379                 if(strcmp(an,"IPC") == 0){
6380                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
6381                 } else {
6382                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
6383                 }
6384         }
6385
6386
6387         if(wc==3){
6388                 if (bc != 0) {
6389                         /*
6390                          * Sometimes this isn't present.
6391                          */
6392
6393                         /* Native FS */
6394                         an = get_unicode_or_ascii_string(tvb, &offset,
6395                                 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
6396                                 &bc);
6397                         if (an == NULL)
6398                                 goto endofcommand;
6399                         proto_tree_add_string(tree, hf_smb_fs, tvb,
6400                                 offset, an_len, an);
6401                         COUNT_BYTES(an_len);
6402                 }
6403         }
6404
6405         END_OF_SMB
6406
6407         /* call AndXCommand (if there are any) */
6408         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6409
6410         return offset;
6411 }
6412
6413
6414
6415 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6416    NT Transaction command  begins here
6417    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
6418 #define NT_TRANS_CREATE         1
6419 #define NT_TRANS_IOCTL          2
6420 #define NT_TRANS_SSD            3
6421 #define NT_TRANS_NOTIFY         4
6422 #define NT_TRANS_RENAME         5
6423 #define NT_TRANS_QSD            6
6424 #define NT_TRANS_GET_USER_QUOTA 7
6425 #define NT_TRANS_SET_USER_QUOTA 8
6426 const value_string nt_cmd_vals[] = {
6427         {NT_TRANS_CREATE,               "NT CREATE"},
6428         {NT_TRANS_IOCTL,                "NT IOCTL"},
6429         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
6430         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
6431         {NT_TRANS_RENAME,               "NT RENAME"},
6432         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
6433         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
6434         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
6435         {0, NULL}
6436 };
6437
6438 static const value_string nt_ioctl_isfsctl_vals[] = {
6439         {0,     "Device IOCTL"},
6440         {1,     "FS control : FSCTL"},
6441         {0, NULL}
6442 };
6443
6444 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
6445 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
6446         "Apply the command to share root handle (MUST BE Dfs)",
6447         "Apply to this share",
6448 };
6449
6450 static const value_string nt_notify_action_vals[] = {
6451         {1,     "ADDED (object was added"},
6452         {2,     "REMOVED (object was removed)"},
6453         {3,     "MODIFIED (object was modified)"},
6454         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
6455         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
6456         {6,     "ADDED_STREAM (a stream was added)"},
6457         {7,     "REMOVED_STREAM (a stream was removed)"},
6458         {8,     "MODIFIED_STREAM (a stream was modified)"},
6459         {0, NULL}
6460 };
6461
6462 static const value_string watch_tree_vals[] = {
6463         {0,     "Current directory only"},
6464         {1,     "Subdirectories also"},
6465         {0, NULL}
6466 };
6467
6468 #define NT_NOTIFY_STREAM_WRITE  0x00000800
6469 #define NT_NOTIFY_STREAM_SIZE   0x00000400
6470 #define NT_NOTIFY_STREAM_NAME   0x00000200
6471 #define NT_NOTIFY_SECURITY      0x00000100
6472 #define NT_NOTIFY_EA            0x00000080
6473 #define NT_NOTIFY_CREATION      0x00000040
6474 #define NT_NOTIFY_LAST_ACCESS   0x00000020
6475 #define NT_NOTIFY_LAST_WRITE    0x00000010
6476 #define NT_NOTIFY_SIZE          0x00000008
6477 #define NT_NOTIFY_ATTRIBUTES    0x00000004
6478 #define NT_NOTIFY_DIR_NAME      0x00000002
6479 #define NT_NOTIFY_FILE_NAME     0x00000001
6480 static const true_false_string tfs_nt_notify_stream_write = {
6481         "Notify on changes to STREAM WRITE",
6482         "Do NOT notify on changes to stream write",
6483 };
6484 static const true_false_string tfs_nt_notify_stream_size = {
6485         "Notify on changes to STREAM SIZE",
6486         "Do NOT notify on changes to stream size",
6487 };
6488 static const true_false_string tfs_nt_notify_stream_name = {
6489         "Notify on changes to STREAM NAME",
6490         "Do NOT notify on changes to stream name",
6491 };
6492 static const true_false_string tfs_nt_notify_security = {
6493         "Notify on changes to SECURITY",
6494         "Do NOT notify on changes to security",
6495 };
6496 static const true_false_string tfs_nt_notify_ea = {
6497         "Notify on changes to EA",
6498         "Do NOT notify on changes to EA",
6499 };
6500 static const true_false_string tfs_nt_notify_creation = {
6501         "Notify on changes to CREATION TIME",
6502         "Do NOT notify on changes to creation time",
6503 };
6504 static const true_false_string tfs_nt_notify_last_access = {
6505         "Notify on changes to LAST ACCESS TIME",
6506         "Do NOT notify on changes to last access time",
6507 };
6508 static const true_false_string tfs_nt_notify_last_write = {
6509         "Notify on changes to LAST WRITE TIME",
6510         "Do NOT notify on changes to last write time",
6511 };
6512 static const true_false_string tfs_nt_notify_size = {
6513         "Notify on changes to SIZE",
6514         "Do NOT notify on changes to size",
6515 };
6516 static const true_false_string tfs_nt_notify_attributes = {
6517         "Notify on changes to ATTRIBUTES",
6518         "Do NOT notify on changes to attributes",
6519 };
6520 static const true_false_string tfs_nt_notify_dir_name = {
6521         "Notify on changes to DIR NAME",
6522         "Do NOT notify on changes to dir name",
6523 };
6524 static const true_false_string tfs_nt_notify_file_name = {
6525         "Notify on changes to FILE NAME",
6526         "Do NOT notify on changes to file name",
6527 };
6528
6529 static const value_string create_disposition_vals[] = {
6530         {0,     "Supersede (supersede existing file (if it exists))"},
6531         {1,     "Open (if file exists open it, else fail)"},
6532         {2,     "Create (if file exists fail, else create it)"},
6533         {3,     "Open If (if file exists open it, else create it)"},
6534         {4,     "Overwrite (if file exists overwrite, else fail)"},
6535         {5,     "Overwrite If (if file exists overwrite, else create it)"},
6536         {0, NULL}
6537 };
6538
6539 static const value_string impersonation_level_vals[] = {
6540         {0,     "Anonymous"},
6541         {1,     "Identification"},
6542         {2,     "Impersonation"},
6543         {3,     "Delegation"},
6544         {0, NULL}
6545 };
6546
6547 static const true_false_string tfs_nt_security_flags_context_tracking = {
6548         "Security tracking mode is DYNAMIC",
6549         "Security tracking mode is STATIC",
6550 };
6551
6552 static const true_false_string tfs_nt_security_flags_effective_only = {
6553         "ONLY ENABLED aspects of the client's security context are available",
6554         "ALL aspects of the client's security context are available",
6555 };
6556
6557 static const true_false_string tfs_nt_create_bits_oplock = {
6558         "Requesting OPLOCK",
6559         "Does NOT request oplock"
6560 };
6561
6562 static const true_false_string tfs_nt_create_bits_boplock = {
6563         "Requesting BATCH OPLOCK",
6564         "Does NOT request batch oplock"
6565 };
6566
6567 /*
6568  * XXX - must be a directory, and can be a file, or can be a directory,
6569  * and must be a file?
6570  */
6571 static const true_false_string tfs_nt_create_bits_dir = {
6572         "Target of open MUST be a DIRECTORY",
6573         "Target of open can be a file"
6574 };
6575
6576 static const true_false_string tfs_nt_create_bits_ext_resp = {
6577   "Extended responses required",
6578   "Extended responses NOT required"
6579 };
6580
6581 static const true_false_string tfs_nt_access_mask_generic_read = {
6582         "GENERIC READ is set",
6583         "Generic read is NOT set"
6584 };
6585 static const true_false_string tfs_nt_access_mask_generic_write = {
6586         "GENERIC WRITE is set",
6587         "Generic write is NOT set"
6588 };
6589 static const true_false_string tfs_nt_access_mask_generic_execute = {
6590         "GENERIC EXECUTE is set",
6591         "Generic execute is NOT set"
6592 };
6593 static const true_false_string tfs_nt_access_mask_generic_all = {
6594         "GENERIC ALL is set",
6595         "Generic all is NOT set"
6596 };
6597 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
6598         "MAXIMUM ALLOWED is set",
6599         "Maximum allowed is NOT set"
6600 };
6601 static const true_false_string tfs_nt_access_mask_system_security = {
6602         "SYSTEM SECURITY is set",
6603         "System security is NOT set"
6604 };
6605 static const true_false_string tfs_nt_access_mask_synchronize = {
6606         "Can wait on handle to SYNCHRONIZE on completion of I/O",
6607         "Can NOT wait on handle to synchronize on completion of I/O"
6608 };
6609 static const true_false_string tfs_nt_access_mask_write_owner = {
6610         "Can WRITE OWNER (take ownership)",
6611         "Can NOT write owner (take ownership)"
6612 };
6613 static const true_false_string tfs_nt_access_mask_write_dac = {
6614         "OWNER may WRITE the DAC",
6615         "Owner may NOT write to the DAC"
6616 };
6617 static const true_false_string tfs_nt_access_mask_read_control = {
6618         "READ ACCESS to owner, group and ACL of the SID",
6619         "Read access is NOT granted to owner, group and ACL of the SID"
6620 };
6621 static const true_false_string tfs_nt_access_mask_delete = {
6622         "DELETE access",
6623         "NO delete access"
6624 };
6625 static const true_false_string tfs_nt_access_mask_write_attributes = {
6626         "WRITE ATTRIBUTES access",
6627         "NO write attributes access"
6628 };
6629 static const true_false_string tfs_nt_access_mask_read_attributes = {
6630         "READ ATTRIBUTES access",
6631         "NO read attributes access"
6632 };
6633 static const true_false_string tfs_nt_access_mask_delete_child = {
6634         "DELETE CHILD access",
6635         "NO delete child access"
6636 };
6637 static const true_false_string tfs_nt_access_mask_execute = {
6638         "EXECUTE access",
6639         "NO execute access"
6640 };
6641 static const true_false_string tfs_nt_access_mask_write_ea = {
6642         "WRITE EXTENDED ATTRIBUTES access",
6643         "NO write extended attributes access"
6644 };
6645 static const true_false_string tfs_nt_access_mask_read_ea = {
6646         "READ EXTENDED ATTRIBUTES access",
6647         "NO read extended attributes access"
6648 };
6649 static const true_false_string tfs_nt_access_mask_append = {
6650         "APPEND access",
6651         "NO append access"
6652 };
6653 static const true_false_string tfs_nt_access_mask_write = {
6654         "WRITE access",
6655         "NO write access"
6656 };
6657 static const true_false_string tfs_nt_access_mask_read = {
6658         "READ access",
6659         "NO read access"
6660 };
6661
6662 static const true_false_string tfs_nt_share_access_delete = {
6663         "Object can be shared for DELETE",
6664         "Object can NOT be shared for delete"
6665 };
6666 static const true_false_string tfs_nt_share_access_write = {
6667         "Object can be shared for WRITE",
6668         "Object can NOT be shared for write"
6669 };
6670 static const true_false_string tfs_nt_share_access_read = {
6671         "Object can be shared for READ",
6672         "Object can NOT be shared for read"
6673 };
6674
6675 static const value_string oplock_level_vals[] = {
6676         {0,     "No oplock granted"},
6677         {1,     "Exclusive oplock granted"},
6678         {2,     "Batch oplock granted"},
6679         {3,     "Level II oplock granted"},
6680         {0, NULL}
6681 };
6682
6683 static const value_string device_type_vals[] = {
6684         {0x00000001,    "Beep"},
6685         {0x00000002,    "CDROM"},
6686         {0x00000003,    "CDROM Filesystem"},
6687         {0x00000004,    "Controller"},
6688         {0x00000005,    "Datalink"},
6689         {0x00000006,    "Dfs"},
6690         {0x00000007,    "Disk"},
6691         {0x00000008,    "Disk Filesystem"},
6692         {0x00000009,    "Filesystem"},
6693         {0x0000000a,    "Inport Port"},
6694         {0x0000000b,    "Keyboard"},
6695         {0x0000000c,    "Mailslot"},
6696         {0x0000000d,    "MIDI-In"},
6697         {0x0000000e,    "MIDI-Out"},
6698         {0x0000000f,    "Mouse"},
6699         {0x00000010,    "Multi UNC Provider"},
6700         {0x00000011,    "Named Pipe"},
6701         {0x00000012,    "Network"},
6702         {0x00000013,    "Network Browser"},
6703         {0x00000014,    "Network Filesystem"},
6704         {0x00000015,    "NULL"},
6705         {0x00000016,    "Parallel Port"},
6706         {0x00000017,    "Physical card"},
6707         {0x00000018,    "Printer"},
6708         {0x00000019,    "Scanner"},
6709         {0x0000001a,    "Serial Mouse port"},
6710         {0x0000001b,    "Serial port"},
6711         {0x0000001c,    "Screen"},
6712         {0x0000001d,    "Sound"},
6713         {0x0000001e,    "Streams"},
6714         {0x0000001f,    "Tape"},
6715         {0x00000020,    "Tape Filesystem"},
6716         {0x00000021,    "Transport"},
6717         {0x00000022,    "Unknown"},
6718         {0x00000023,    "Video"},
6719         {0x00000024,    "Virtual Disk"},
6720         {0x00000025,    "WAVE-In"},
6721         {0x00000026,    "WAVE-Out"},
6722         {0x00000027,    "8042 Port"},
6723         {0x00000028,    "Network Redirector"},
6724         {0x00000029,    "Battery"},
6725         {0x0000002a,    "Bus Extender"},
6726         {0x0000002b,    "Modem"},
6727         {0x0000002c,    "VDM"},
6728         {0,     NULL}
6729 };
6730
6731 static const value_string is_directory_vals[] = {
6732         {0,     "This is NOT a directory"},
6733         {1,     "This is a DIRECTORY"},
6734         {0, NULL}
6735 };
6736
6737 typedef struct _nt_trans_data {
6738         int subcmd;
6739         guint32 sd_len;
6740         guint32 ea_len;
6741 } nt_trans_data;
6742
6743
6744
6745 static int
6746 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6747 {
6748         guint8 mask;
6749         proto_item *item = NULL;
6750         proto_tree *tree = NULL;
6751
6752         mask = tvb_get_guint8(tvb, offset);
6753
6754         if(parent_tree){
6755                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6756                         "Security Flags: 0x%02x", mask);
6757                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
6758         }
6759
6760         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
6761                 tvb, offset, 1, mask);
6762         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
6763                 tvb, offset, 1, mask);
6764
6765         offset += 1;
6766
6767         return offset;
6768 }
6769
6770 static int
6771 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6772 {
6773         guint32 mask;
6774         proto_item *item = NULL;
6775         proto_tree *tree = NULL;
6776
6777         mask = tvb_get_letohl(tvb, offset);
6778
6779         if(parent_tree){
6780                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6781                         "Share Access: 0x%08x", mask);
6782                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
6783         }
6784
6785         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
6786                 tvb, offset, 4, mask);
6787         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
6788                 tvb, offset, 4, mask);
6789         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
6790                 tvb, offset, 4, mask);
6791
6792         offset += 4;
6793
6794         return offset;
6795 }
6796
6797 /* FIXME: need to call dissect_nt_access_mask() instead */
6798
6799 static int
6800 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6801 {
6802         guint32 mask;
6803         proto_item *item = NULL;
6804         proto_tree *tree = NULL;
6805
6806         mask = tvb_get_letohl(tvb, offset);
6807
6808         if(parent_tree){
6809                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6810                         "Access Mask: 0x%08x", mask);
6811                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
6812         }
6813
6814         /*
6815          * Some of these bits come from
6816          *
6817          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6818          *
6819          * and others come from the section on ZwOpenFile in "Windows(R)
6820          * NT(R)/2000 Native API Reference".
6821          */
6822         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
6823                 tvb, offset, 4, mask);
6824         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
6825                 tvb, offset, 4, mask);
6826         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
6827                 tvb, offset, 4, mask);
6828         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
6829                 tvb, offset, 4, mask);
6830         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
6831                 tvb, offset, 4, mask);
6832         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
6833                 tvb, offset, 4, mask);
6834         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
6835                 tvb, offset, 4, mask);
6836         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
6837                 tvb, offset, 4, mask);
6838         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
6839                 tvb, offset, 4, mask);
6840         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
6841                 tvb, offset, 4, mask);
6842         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
6843                 tvb, offset, 4, mask);
6844         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
6845                 tvb, offset, 4, mask);
6846         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
6847                 tvb, offset, 4, mask);
6848         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
6849                 tvb, offset, 4, mask);
6850         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
6851                 tvb, offset, 4, mask);
6852         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
6853                 tvb, offset, 4, mask);
6854         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
6855                 tvb, offset, 4, mask);
6856         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
6857                 tvb, offset, 4, mask);
6858         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
6859                 tvb, offset, 4, mask);
6860         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
6861                 tvb, offset, 4, mask);
6862
6863         offset += 4;
6864
6865         return offset;
6866 }
6867
6868 static int
6869 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6870 {
6871         guint32 mask;
6872         proto_item *item = NULL;
6873         proto_tree *tree = NULL;
6874
6875         mask = tvb_get_letohl(tvb, offset);
6876
6877         if(parent_tree){
6878                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6879                         "Create Flags: 0x%08x", mask);
6880                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
6881         }
6882
6883         /*
6884          * XXX - it's 0x00000016 in at least one capture, but
6885          * Network Monitor doesn't say what the 0x00000010 bit is.
6886          * Does the Win32 API documentation, or NT Native API book,
6887          * suggest anything?
6888          *
6889          * That is the extended response desired bit ... RJS, from Samba
6890          * Well, maybe. Samba thinks it is, and uses it to encode
6891          * OpLock granted as the high order bit of the Action field
6892          * in the response. However, Windows does not do that. Or at least
6893          * Win2K doesn't.
6894          */
6895         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
6896                                tvb, offset, 4, mask);
6897         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
6898                 tvb, offset, 4, mask);
6899         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
6900                 tvb, offset, 4, mask);
6901         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
6902                 tvb, offset, 4, mask);
6903
6904         offset += 4;
6905
6906         return offset;
6907 }
6908
6909 /*
6910  * XXX - there are some more flags in the description of "ZwOpenFile()"
6911  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
6912  * the wire as well?  (The spec at
6913  *
6914  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6915  *
6916  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
6917  * via the SMB protocol.  The NT redirector should convert this option
6918  * to FILE_WRITE_THROUGH."
6919  *
6920  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
6921  * values one would infer from their position in the list of flags for
6922  * "ZwOpenFile()".  Most of the others probably have those values
6923  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
6924  * which might go over the wire (for the benefit of backup/restore software).
6925  */
6926 static const true_false_string tfs_nt_create_options_directory = {
6927         "File being created/opened must be a directory",
6928         "File being created/opened must not be a directory"
6929 };
6930 static const true_false_string tfs_nt_create_options_write_through = {
6931         "Writes should flush buffered data before completing",
6932         "Writes need not flush buffered data before completing"
6933 };
6934 static const true_false_string tfs_nt_create_options_sequential_only = {
6935         "The file will only be accessed sequentially",
6936         "The file might not only be accessed sequentially"
6937 };
6938 static const true_false_string tfs_nt_create_options_sync_io_alert = {
6939         "All operations SYNCHRONOUS, waits subject to termination from alert",
6940         "Operations NOT necessarily synchronous"
6941 };
6942 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
6943         "All operations SYNCHRONOUS, waits not subject to alert",
6944         "Operations NOT necessarily synchronous"
6945 };
6946 static const true_false_string tfs_nt_create_options_non_directory = {
6947         "File being created/opened must not be a directory",
6948         "File being created/opened must be a directory"
6949 };
6950 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
6951         "The client does not understand extended attributes",
6952         "The client understands extended attributes"
6953 };
6954 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
6955         "The client understands only 8.3 file names",
6956         "The client understands long file names"
6957 };
6958 static const true_false_string tfs_nt_create_options_random_access = {
6959         "The file will be accessed randomly",
6960         "The file will not be accessed randomly"
6961 };
6962 static const true_false_string tfs_nt_create_options_delete_on_close = {
6963         "The file should be deleted when it is closed",
6964         "The file should not be deleted when it is closed"
6965 };
6966
6967 static int
6968 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6969 {
6970         guint32 mask;
6971         proto_item *item = NULL;
6972         proto_tree *tree = NULL;
6973
6974         mask = tvb_get_letohl(tvb, offset);
6975
6976         if(parent_tree){
6977                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6978                         "Create Options: 0x%08x", mask);
6979                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
6980         }
6981
6982         /*
6983          * From
6984          *
6985          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6986          */
6987         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
6988                 tvb, offset, 4, mask);
6989         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
6990                 tvb, offset, 4, mask);
6991         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
6992                 tvb, offset, 4, mask);
6993         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
6994                 tvb, offset, 4, mask);
6995         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
6996                 tvb, offset, 4, mask);
6997         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
6998                 tvb, offset, 4, mask);
6999         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
7000                 tvb, offset, 4, mask);
7001         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
7002                 tvb, offset, 4, mask);
7003         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
7004                 tvb, offset, 4, mask);
7005         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
7006                 tvb, offset, 4, mask);
7007
7008         offset += 4;
7009
7010         return offset;
7011 }
7012
7013 static int
7014 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7015 {
7016         guint32 mask;
7017         proto_item *item = NULL;
7018         proto_tree *tree = NULL;
7019
7020         mask = tvb_get_letohl(tvb, offset);
7021
7022         if(parent_tree){
7023                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7024                         "Completion Filter: 0x%08x", mask);
7025                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
7026         }
7027
7028         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
7029                 tvb, offset, 4, mask);
7030         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
7031                 tvb, offset, 4, mask);
7032         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
7033                 tvb, offset, 4, mask);
7034         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
7035                 tvb, offset, 4, mask);
7036         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
7037                 tvb, offset, 4, mask);
7038         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
7039                 tvb, offset, 4, mask);
7040         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
7041                 tvb, offset, 4, mask);
7042         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
7043                 tvb, offset, 4, mask);
7044         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
7045                 tvb, offset, 4, mask);
7046         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
7047                 tvb, offset, 4, mask);
7048         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
7049                 tvb, offset, 4, mask);
7050         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
7051                 tvb, offset, 4, mask);
7052
7053         offset += 4;
7054         return offset;
7055 }
7056
7057 static int
7058 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7059 {
7060         guint8 mask;
7061         proto_item *item = NULL;
7062         proto_tree *tree = NULL;
7063
7064         mask = tvb_get_guint8(tvb, offset);
7065
7066         if(parent_tree){
7067                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7068                         "Completion Filter: 0x%02x", mask);
7069                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
7070         }
7071
7072         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
7073                 tvb, offset, 1, mask);
7074
7075         offset += 1;
7076         return offset;
7077 }
7078
7079 /*
7080  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
7081  * Native API Reference".
7082  */
7083 static const true_false_string tfs_nt_qsd_owner = {
7084         "Requesting OWNER security information",
7085         "NOT requesting owner security information",
7086 };
7087
7088 static const true_false_string tfs_nt_qsd_group = {
7089         "Requesting GROUP security information",
7090         "NOT requesting group security information",
7091 };
7092
7093 static const true_false_string tfs_nt_qsd_dacl = {
7094         "Requesting DACL security information",
7095         "NOT requesting DACL security information",
7096 };
7097
7098 static const true_false_string tfs_nt_qsd_sacl = {
7099         "Requesting SACL security information",
7100         "NOT requesting SACL security information",
7101 };
7102
7103 #define NT_QSD_OWNER    0x00000001
7104 #define NT_QSD_GROUP    0x00000002
7105 #define NT_QSD_DACL     0x00000004
7106 #define NT_QSD_SACL     0x00000008
7107
7108 static int
7109 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7110 {
7111         guint32 mask;
7112         proto_item *item = NULL;
7113         proto_tree *tree = NULL;
7114
7115         mask = tvb_get_letohl(tvb, offset);
7116
7117         if(parent_tree){
7118                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7119                         "Security Information: 0x%08x", mask);
7120                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
7121         }
7122
7123         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
7124                 tvb, offset, 4, mask);
7125         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
7126                 tvb, offset, 4, mask);
7127         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
7128                 tvb, offset, 4, mask);
7129         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
7130                 tvb, offset, 4, mask);
7131
7132         offset += 4;
7133
7134         return offset;
7135 }
7136
7137 static void
7138 free_g_string(void *arg)
7139 {
7140         g_string_free(arg, TRUE);
7141 }
7142
7143 /* Dissect a NT SID.  Label it with 'name' and return a string version of
7144    the SID in the 'sid_str' parameter which must be freed by the caller.
7145    hf_sid can be -1 if the caller doesnt care what name is used and then 
7146    "smb.sid" will be the default instead. If the caller wants a more
7147    appropriate hf field, it will just pass a FT_STRING hf field here
7148 */
7149
7150 int
7151 dissect_nt_sid(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name,
7152                char **sid_str, int hf_sid)
7153 {
7154         proto_item *item = NULL;
7155         proto_tree *tree = NULL;
7156         int old_offset = offset, sa_offset = offset;
7157         gboolean rid_present;
7158         guint rid=0;
7159         int rid_offset=0;
7160         guint8 revision;
7161         int rev_offset;
7162         guint8 num_auth;
7163         int na_offset;
7164         guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
7165         int i;
7166         GString *gstr;
7167         char sid_string[245];
7168         char *sid_name;
7169
7170         if(hf_sid==-1){
7171                 hf_sid=hf_smb_sid;
7172         }
7173
7174         /* revision of sid */
7175         revision = tvb_get_guint8(tvb, offset);
7176         rev_offset = offset;
7177         offset += 1;
7178
7179         switch(revision){
7180         case 1:
7181         case 2:  /* Not sure what the different revision numbers mean */
7182           /* number of authorities*/
7183           num_auth = tvb_get_guint8(tvb, offset);
7184           na_offset = offset;
7185           offset += 1;
7186
7187           /* XXX perhaps we should have these thing searchable?
7188              a new FT_xxx thingie? SMB is quite common!*/
7189           /* identifier authorities */
7190
7191           for(i=0;i<6;i++){
7192             auth = (auth << 8) + tvb_get_guint8(tvb, offset);
7193
7194             offset++;
7195           }
7196
7197           sa_offset = offset;
7198
7199           gstr = g_string_new("");
7200
7201           CLEANUP_PUSH(free_g_string, gstr);
7202
7203           /* sub authorities, leave RID to last */
7204           for(i=0; i < (num_auth > 4?(num_auth - 1):num_auth); i++){
7205             /*
7206              * XXX should not be letohl but native byteorder according to
7207              * Samba header files.
7208              *
7209              * However, considering that there were never any NT ports
7210              * to big-endian platforms (PowerPC and MIPS ran little-endian,
7211              * and IA-64 runs little-endian, as does x86-64), we can (?)
7212              * assume that non le byte encodings will be "uncommon"?
7213              */
7214              g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"),
7215                   tvb_get_letohl(tvb, offset));
7216              offset+=4;
7217           }
7218
7219
7220           if (num_auth > 4) {
7221             rid = tvb_get_letohl(tvb, offset);
7222             rid_present=TRUE;
7223             rid_offset=offset;
7224             offset+=4;
7225             sprintf(sid_string, "S-1-%u-%s-%u", auth, gstr->str, rid);
7226           } else {
7227             rid_present=FALSE;
7228             sprintf(sid_string, "S-1-%u-%s", auth, gstr->str);
7229           }
7230
7231           sid_name=NULL;
7232           if(sid_name_snooping){
7233             sid_name=find_sid_name(sid_string);
7234           }
7235
7236           if(parent_tree){
7237             if(sid_name){
7238               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);
7239             } else {
7240               item = proto_tree_add_string_format(parent_tree, hf_sid, tvb, old_offset, offset-old_offset, sid_string, "%s: %s", name, sid_string);
7241             }
7242             tree = proto_item_add_subtree(item, ett_smb_sid);
7243           }
7244
7245           proto_tree_add_item(tree, hf_smb_sid_revision, tvb, rev_offset, 1, TRUE);
7246           proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, na_offset, 1, TRUE);
7247           proto_tree_add_text(tree, tvb, na_offset+1, 6, "Authority: %u", auth);
7248           proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
7249
7250           if(rid_present){
7251             proto_tree_add_text(tree, tvb, rid_offset, 4, "RID: %u", rid);
7252           }
7253
7254           if(sid_str){
7255             if(sid_name){
7256               *sid_str = g_strdup_printf("%s (%s)", sid_string, sid_name);
7257             } else {
7258               *sid_str = g_strdup(sid_string);
7259             }
7260           }
7261
7262           CLEANUP_CALL_AND_POP;
7263         }
7264
7265
7266         return offset;
7267 }
7268
7269
7270 static const value_string ace_type_vals[] = {
7271   { 0, "Access Allowed"},
7272   { 1, "Access Denied"},
7273   { 2, "System Audit"},
7274   { 3, "System Alarm"},
7275   { 0, NULL}
7276 };
7277 static const true_false_string tfs_ace_flags_object_inherit = {
7278   "Subordinate files will inherit this ACE",
7279   "Subordinate files will not inherit this ACE"
7280 };
7281 static const true_false_string tfs_ace_flags_container_inherit = {
7282   "Subordinate containers will inherit this ACE",
7283   "Subordinate containers will not inherit this ACE"
7284 };
7285 static const true_false_string tfs_ace_flags_non_propagate_inherit = {
7286   "Subordinate object will not propagate the inherited ACE further",
7287   "Subordinate object will propagate the inherited ACE further"
7288 };
7289 static const true_false_string tfs_ace_flags_inherit_only = {
7290   "This ACE does not apply to the current object",
7291   "This ACE applies to the current object"
7292 };
7293 static const true_false_string tfs_ace_flags_inherited_ace = {
7294   "This ACE was inherited from its parent object",
7295   "This ACE was not inherited from its parent object"
7296 };
7297 static const true_false_string tfs_ace_flags_successful_access = {
7298   "Successful accesses will be audited",
7299   "Successful accesses will not be audited"
7300 };
7301 static const true_false_string tfs_ace_flags_failed_access = {
7302   "Failed accesses will be audited",
7303   "Failed accesses will not be audited"
7304 };
7305
7306 #define APPEND_ACE_TEXT(flag, item, string) \
7307         if(flag){                                                       \
7308                 if(item)                                                \
7309                         proto_item_append_text(item, string, sep);      \
7310                 sep = ", ";                                             \
7311         }
7312
7313 static int
7314 dissect_nt_v2_ace_flags(tvbuff_t *tvb, int offset, proto_tree *parent_tree,
7315                         guint8 *data)
7316 {
7317         proto_item *item = NULL;
7318         proto_tree *tree = NULL;
7319         guint8 mask;
7320         char *sep = " ";
7321
7322         mask = tvb_get_guint8(tvb, offset);
7323
7324         if (data)
7325                 *data = mask;
7326
7327
7328         if(parent_tree){
7329                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7330                                            "NT ACE Flags: 0x%02x", mask);
7331                 tree = proto_item_add_subtree(item, ett_smb_ace_flags);
7332         }
7333
7334         proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
7335                        tvb, offset, 1, mask);
7336         APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
7337
7338         proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
7339                        tvb, offset, 1, mask);
7340         APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
7341
7342         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
7343                        tvb, offset, 1, mask);
7344         APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
7345
7346         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
7347                        tvb, offset, 1, mask);
7348         APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
7349
7350         proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
7351                        tvb, offset, 1, mask);
7352         APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
7353
7354         proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
7355                        tvb, offset, 1, mask);
7356         APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
7357
7358         proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
7359                        tvb, offset, 1, mask);
7360         APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
7361
7362
7363         offset += 1;
7364         return offset;
7365 }
7366
7367 /* Dissect an access mask.  All this stuff is kind of explained at MSDN:
7368
7369 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/windows_2000_windows_nt_access_mask_format.asp
7370
7371 */
7372
7373 static gint ett_nt_access_mask = -1;
7374 static gint ett_nt_access_mask_generic = -1;
7375 static gint ett_nt_access_mask_standard = -1;
7376 static gint ett_nt_access_mask_specific = -1;
7377
7378 static int hf_access_sacl = -1;
7379 static int hf_access_maximum_allowed = -1;
7380 static int hf_access_generic_read = -1;
7381 static int hf_access_generic_write = -1;
7382 static int hf_access_generic_execute = -1;
7383 static int hf_access_generic_all = -1;
7384 static int hf_access_standard_delete = -1;
7385 static int hf_access_standard_read_control = -1;
7386 static int hf_access_standard_synchronise = -1;
7387 static int hf_access_standard_write_dac = -1;
7388 static int hf_access_standard_write_owner = -1;
7389 static int hf_access_specific_15 = -1;
7390 static int hf_access_specific_14 = -1;
7391 static int hf_access_specific_13 = -1;
7392 static int hf_access_specific_12 = -1;
7393 static int hf_access_specific_11 = -1;
7394 static int hf_access_specific_10 = -1;
7395 static int hf_access_specific_9 = -1;
7396 static int hf_access_specific_8 = -1;
7397 static int hf_access_specific_7 = -1;
7398 static int hf_access_specific_6 = -1;
7399 static int hf_access_specific_5 = -1;
7400 static int hf_access_specific_4 = -1;
7401 static int hf_access_specific_3 = -1;
7402 static int hf_access_specific_2 = -1;
7403 static int hf_access_specific_1 = -1;
7404 static int hf_access_specific_0 = -1;
7405
7406 /* Map generic permissions to specific permissions */
7407
7408 static void map_generic_access(guint32 *access_mask, 
7409                                struct generic_mapping *mapping)
7410 {
7411         if (*access_mask & GENERIC_READ_ACCESS) {
7412                 *access_mask &= ~GENERIC_READ_ACCESS;
7413                 *access_mask |= mapping->generic_read;
7414         }
7415
7416         if (*access_mask & GENERIC_WRITE_ACCESS) {
7417                 *access_mask &= ~GENERIC_WRITE_ACCESS;
7418                 *access_mask |= mapping->generic_write;
7419         }
7420
7421         if (*access_mask & GENERIC_EXECUTE_ACCESS) {
7422                 *access_mask &= ~GENERIC_EXECUTE_ACCESS;
7423                 *access_mask |= mapping->generic_execute;
7424         }
7425
7426         if (*access_mask & GENERIC_ALL_ACCESS) {
7427                 *access_mask &= ~GENERIC_ALL_ACCESS;
7428                 *access_mask |= mapping->generic_all;
7429         }
7430 }
7431
7432 /* Map standard permissions to specific permissions */
7433
7434 static void map_standard_access(guint32 *access_mask,
7435                                 struct standard_mapping *mapping)
7436 {
7437         if (*access_mask & READ_CONTROL_ACCESS) {
7438                 *access_mask &= ~READ_CONTROL_ACCESS;
7439                 *access_mask |= mapping->std_read;
7440         }
7441
7442         if (*access_mask & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|
7443                             SYNCHRONIZE_ACCESS)) {
7444                 *access_mask &= ~(DELETE_ACCESS|WRITE_DAC_ACCESS|
7445                                   WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS);
7446                 *access_mask |= mapping->std_all;
7447         }
7448
7449 }
7450
7451 int
7452 dissect_nt_access_mask(tvbuff_t *tvb, gint offset, packet_info *pinfo,
7453                        proto_tree *tree, char *drep, int hfindex,
7454                        struct access_mask_info *ami)
7455 {
7456         proto_item *item;
7457         proto_tree *subtree, *generic_tree, *standard_tree, *specific_tree;
7458         guint32 access;
7459
7460         if (drep != NULL) {
7461                 /*
7462                  * Called from a DCE RPC protocol dissector, for a
7463                  * protocol where a 32-bit NDR integer contains
7464                  * an NT access mask; extract the access mask
7465                  * with an NDR call.
7466                  */
7467                 offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
7468                                             hfindex, &access);
7469         } else {
7470                 /*
7471                  * Called from SMB, where the access mask is just a
7472                  * 4-byte little-endian quantity with no special
7473                  * NDR alignment requirement; extract it with
7474                  * "tvb_get_letohl()".
7475                  */
7476                 access = tvb_get_letohl(tvb, offset);
7477                 offset += 4;
7478         }
7479
7480         item = proto_tree_add_uint(tree, hfindex, tvb, offset - 4, 4, access);
7481
7482         subtree = proto_item_add_subtree(item, ett_nt_access_mask);
7483
7484         /* Generic access rights */
7485
7486         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7487                                    "Generic rights: 0x%08x",
7488                                    access & GENERIC_RIGHTS_MASK);
7489
7490         generic_tree = proto_item_add_subtree(
7491                 item, ett_nt_access_mask_generic);
7492
7493         proto_tree_add_boolean(
7494                 generic_tree, hf_access_generic_read, tvb, offset - 4, 4,
7495                 access);
7496
7497         proto_tree_add_boolean(
7498                 generic_tree, hf_access_generic_write, tvb, offset - 4, 4,
7499                 access);
7500
7501         proto_tree_add_boolean(
7502                 generic_tree, hf_access_generic_execute, tvb, offset - 4, 4,
7503                 access);
7504
7505         proto_tree_add_boolean(
7506                 generic_tree, hf_access_generic_all, tvb, offset - 4, 4,
7507                 access);
7508
7509         /* Reserved (??) */
7510
7511         proto_tree_add_boolean(
7512                 subtree, hf_access_maximum_allowed, tvb, offset - 4, 4,
7513                 access);
7514
7515         /* Access system security */
7516
7517         proto_tree_add_boolean(
7518                 subtree, hf_access_sacl, tvb, offset - 4, 4,
7519                 access);
7520
7521         /* Standard access rights */
7522
7523         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7524                                    "Standard rights: 0x%08x",
7525                                    access & STANDARD_RIGHTS_MASK);
7526
7527         standard_tree = proto_item_add_subtree(
7528                 item, ett_nt_access_mask_standard);
7529
7530         proto_tree_add_boolean(
7531                 standard_tree, hf_access_standard_synchronise, tvb, 
7532                 offset - 4, 4, access);
7533
7534         proto_tree_add_boolean(
7535                 standard_tree, hf_access_standard_write_owner, tvb, 
7536                 offset - 4, 4, access);
7537
7538         proto_tree_add_boolean(
7539                 standard_tree, hf_access_standard_write_dac, tvb, 
7540                 offset - 4, 4, access);
7541
7542         proto_tree_add_boolean(
7543                 standard_tree, hf_access_standard_read_control, tvb, 
7544                 offset - 4, 4, access);
7545
7546         proto_tree_add_boolean(
7547                 standard_tree, hf_access_standard_delete, tvb, offset - 4, 4,
7548                 access);
7549
7550         /* Specific access rights.  Call the specific_rights_fn
7551            pointer if we have one, otherwise just display bits 0-15 in
7552            boring fashion. */
7553
7554         if (ami && ami->specific_rights_name)
7555                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7556                                            "%s specific rights: 0x%08x",
7557                                            ami->specific_rights_name,
7558                                            access & SPECIFIC_RIGHTS_MASK);
7559         else
7560                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7561                                            "Specific rights: 0x%08x",
7562                                            access & SPECIFIC_RIGHTS_MASK);
7563
7564         specific_tree = proto_item_add_subtree(
7565                 item, ett_nt_access_mask_specific);
7566
7567         if (ami && ami->specific_rights_fn) {
7568                 guint32 mapped_access = access;
7569                 proto_tree *specific_mapped;
7570
7571                 specific_mapped = proto_item_add_subtree(
7572                         item, ett_nt_access_mask_specific);
7573
7574                 ami->specific_rights_fn(
7575                         tvb, offset - 4, specific_tree, access);
7576
7577                 if (ami->generic_mapping)
7578                         map_generic_access(&access, ami->generic_mapping);
7579                 
7580                 if (ami->standard_mapping)
7581                         map_standard_access(&access, ami->standard_mapping);
7582
7583                 if (access != mapped_access) {
7584                         ami->specific_rights_fn(
7585                                 tvb, offset - 4, specific_mapped, 
7586                                 mapped_access);
7587                 }
7588                 
7589                 return offset;
7590         }
7591
7592         proto_tree_add_boolean(
7593                 specific_tree, hf_access_specific_15, tvb, offset - 4, 4,
7594                 access);
7595
7596         proto_tree_add_boolean(
7597                 specific_tree, hf_access_specific_14, tvb, offset - 4, 4,
7598                 access);
7599
7600         proto_tree_add_boolean(
7601                 specific_tree, hf_access_specific_13, tvb, offset - 4, 4,
7602                 access);
7603
7604         proto_tree_add_boolean(
7605                 specific_tree, hf_access_specific_12, tvb, offset - 4, 4,
7606                 access);
7607
7608         proto_tree_add_boolean(
7609                 specific_tree, hf_access_specific_11, tvb, offset - 4, 4,
7610                 access);
7611
7612         proto_tree_add_boolean(
7613                 specific_tree, hf_access_specific_10, tvb, offset - 4, 4,
7614                 access);
7615
7616         proto_tree_add_boolean(
7617                 specific_tree, hf_access_specific_9, tvb, offset - 4, 4,
7618                 access);
7619
7620         proto_tree_add_boolean(
7621                 specific_tree, hf_access_specific_8, tvb, offset - 4, 4,
7622                 access);
7623
7624         proto_tree_add_boolean(
7625                 specific_tree, hf_access_specific_7, tvb, offset - 4, 4,
7626                 access);
7627
7628         proto_tree_add_boolean(
7629                 specific_tree, hf_access_specific_6, tvb, offset - 4, 4,
7630                 access);
7631
7632         proto_tree_add_boolean(
7633                 specific_tree, hf_access_specific_5, tvb, offset - 4, 4,
7634                 access);
7635
7636         proto_tree_add_boolean(
7637                 specific_tree, hf_access_specific_4, tvb, offset - 4, 4,
7638                 access);
7639
7640         proto_tree_add_boolean(
7641                 specific_tree, hf_access_specific_3, tvb, offset - 4, 4,
7642                 access);
7643
7644         proto_tree_add_boolean(
7645                 specific_tree, hf_access_specific_2, tvb, offset - 4, 4,
7646                 access);
7647
7648         proto_tree_add_boolean(
7649                 specific_tree, hf_access_specific_1, tvb, offset - 4, 4,
7650                 access);
7651
7652         proto_tree_add_boolean(
7653                 specific_tree, hf_access_specific_0, tvb, offset - 4, 4,
7654                 access);
7655
7656         return offset;
7657 }
7658
7659 static int hf_smb_access_mask = -1;
7660
7661 static int
7662 dissect_nt_v2_ace(tvbuff_t *tvb, int offset, packet_info *pinfo,
7663                   proto_tree *parent_tree, char *drep,
7664                   struct access_mask_info *ami)
7665 {
7666         proto_item *item = NULL;
7667         proto_tree *tree = NULL;
7668         int old_offset = offset;
7669         guint16 size;
7670         char *sid_str = NULL;
7671         guint8 type;
7672         guint8 flags;
7673
7674         if(parent_tree){
7675                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7676                                            "NT ACE: ");
7677                 tree = proto_item_add_subtree(item, ett_smb_ace);
7678         }
7679
7680         /* type */
7681         type = tvb_get_guint8(tvb, offset);
7682         proto_tree_add_uint(tree, hf_smb_ace_type, tvb, offset, 1, type);
7683         offset += 1;
7684
7685         /* flags */
7686         offset = dissect_nt_v2_ace_flags(tvb, offset, tree, &flags);
7687
7688         /* size */
7689         size = tvb_get_letohs(tvb, offset);
7690         proto_tree_add_uint(tree, hf_smb_ace_size, tvb, offset, 2, size);
7691         offset += 2;
7692
7693         /* access mask */
7694         offset = dissect_nt_access_mask(
7695                 tvb, offset, pinfo, tree, drep, hf_smb_access_mask, ami);
7696
7697         /* SID */
7698         offset = dissect_nt_sid(tvb, offset, tree, "ACE", &sid_str, -1);
7699
7700         if (item)
7701                 proto_item_append_text(
7702                         item, "%s, flags 0x%02x, %s", sid_str, flags,
7703                         val_to_str(type, ace_type_vals, "Unknown ACE type (0x%02x)"));
7704
7705         g_free(sid_str);
7706
7707         proto_item_set_len(item, offset-old_offset);
7708
7709         /* Sometimes there is some spare space at the end of the ACE so use
7710            the size field to work out where the end is. */
7711
7712         return old_offset + size;
7713 }
7714
7715 static int
7716 dissect_nt_acl(tvbuff_t *tvb, int offset, packet_info *pinfo,
7717                proto_tree *parent_tree, char *drep, char *name,
7718                struct access_mask_info *ami)
7719 {
7720         proto_item *item = NULL;
7721         proto_tree *tree = NULL;
7722         int old_offset = offset;
7723         guint16 revision;
7724         guint32 num_aces;
7725
7726         if(parent_tree){
7727                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7728                                            "NT %s ACL", name);
7729                 tree = proto_item_add_subtree(item, ett_smb_acl);
7730         }
7731
7732         /* revision */
7733         revision = tvb_get_letohs(tvb, offset);
7734         proto_tree_add_uint(tree, hf_smb_acl_revision,
7735                 tvb, offset, 2, revision);
7736         offset += 2;
7737
7738         switch(revision){
7739         case 2:  /* only version we will ever see of this structure?*/
7740         case 3:
7741           /* size */
7742           proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
7743           offset += 2;
7744
7745           /* number of ace structures */
7746           num_aces = tvb_get_letohl(tvb, offset);
7747           proto_tree_add_uint(tree, hf_smb_acl_num_aces,
7748                               tvb, offset, 4, num_aces);
7749           offset += 4;
7750
7751           while(num_aces--){
7752             offset=dissect_nt_v2_ace(
7753                     tvb, offset, pinfo, tree, drep, ami);
7754           }
7755         }
7756
7757         proto_item_set_len(item, offset-old_offset);
7758         return offset;
7759 }
7760
7761 static const true_false_string tfs_sec_desc_type_owner_defaulted = {
7762   "OWNER is DEFAULTED",
7763   "Owner is NOT defaulted"
7764 };
7765 static const true_false_string tfs_sec_desc_type_group_defaulted = {
7766   "GROUP is DEFAULTED",
7767   "Group is NOT defaulted"
7768 };
7769 static const true_false_string tfs_sec_desc_type_dacl_present = {
7770   "DACL is PRESENT",
7771   "DACL is NOT present"
7772 };
7773 static const true_false_string tfs_sec_desc_type_dacl_defaulted = {
7774   "DACL is DEFAULTED",
7775   "DACL is NOT defaulted"
7776 };
7777 static const true_false_string tfs_sec_desc_type_sacl_present = {
7778   "SACL is PRESENT",
7779   "SACL is NOT present"
7780 };
7781 static const true_false_string tfs_sec_desc_type_sacl_defaulted = {
7782   "SACL is DEFAULTED",
7783   "SACL is NOT defaulted"
7784 };
7785 static const true_false_string tfs_sec_desc_type_dacl_auto_inherit_req = {
7786   "DACL has AUTO INHERIT REQUIRED",
7787   "DACL does NOT require auto inherit"
7788 };
7789 static const true_false_string tfs_sec_desc_type_sacl_auto_inherit_req = {
7790   "SACL has AUTO INHERIT REQUIRED",
7791   "SACL does NOT require auto inherit"
7792 };
7793 static const true_false_string tfs_sec_desc_type_dacl_auto_inherited = {
7794   "DACL is AUTO INHERITED",
7795   "DACL is NOT auto inherited"
7796 };
7797 static const true_false_string tfs_sec_desc_type_sacl_auto_inherited = {
7798   "SACL is AUTO INHERITED",
7799   "SACL is NOT auto inherited"
7800 };
7801 static const true_false_string tfs_sec_desc_type_dacl_protected = {
7802   "The DACL is PROTECTED",
7803   "The DACL is NOT protected"
7804 };
7805 static const true_false_string tfs_sec_desc_type_sacl_protected = {
7806   "The SACL is PROTECTED",
7807   "The SACL is NOT protected"
7808 };
7809 static const true_false_string tfs_sec_desc_type_self_relative = {
7810   "This SecDesc is SELF RELATIVE",
7811   "This SecDesc is NOT self relative"
7812 };
7813
7814
7815 static int
7816 dissect_nt_sec_desc_type(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7817 {
7818         proto_item *item = NULL;
7819         proto_tree *tree = NULL;
7820         guint16 mask;
7821
7822         mask = tvb_get_letohs(tvb, offset);
7823         if(parent_tree){
7824                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7825                                            "Type: 0x%04x", mask);
7826                 tree = proto_item_add_subtree(item, ett_smb_sec_desc_type);
7827         }
7828
7829         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_self_relative,
7830                                tvb, offset, 2, mask);
7831         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_protected,
7832                                tvb, offset, 2, mask);
7833         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_protected,
7834                                tvb, offset, 2, mask);
7835         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherited,
7836                                tvb, offset, 2, mask);
7837         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherited,
7838                                tvb, offset, 2, mask);
7839         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherit_req,
7840                                tvb, offset, 2, mask);
7841         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherit_req,
7842                                tvb, offset, 2, mask);
7843         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_defaulted,
7844                                tvb, offset, 2, mask);
7845         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_present,
7846                                tvb, offset, 2, mask);
7847         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_defaulted,
7848                                tvb, offset, 2, mask);
7849         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_present,
7850                                tvb, offset, 2, mask);
7851         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_group_defaulted,
7852                                tvb, offset, 2, mask);
7853         proto_tree_add_boolean(tree, hf_smb_sec_desc_type_owner_defaulted,
7854                                tvb, offset, 2, mask);
7855
7856
7857         offset += 2;
7858         return offset;
7859 }
7860
7861 int
7862 dissect_nt_sec_desc(tvbuff_t *tvb, int offset, packet_info *pinfo,
7863                     proto_tree *parent_tree, char *drep, int len, 
7864                     struct access_mask_info *ami)
7865 {
7866         proto_item *item = NULL;
7867         proto_tree *tree = NULL;
7868         guint8 revision;
7869         int old_offset = offset;
7870         guint32 owner_sid_offset;
7871         guint32 group_sid_offset;
7872         guint32 sacl_offset;
7873         guint32 dacl_offset;
7874
7875         if(parent_tree){
7876                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7877                                            "NT Security Descriptor");
7878                 tree = proto_item_add_subtree(item, ett_smb_sec_desc);
7879         }
7880
7881         /* revision */
7882         revision = tvb_get_guint8(tvb, offset);
7883         proto_tree_add_uint(tree, hf_smb_sec_desc_revision,
7884                 tvb, offset, 1, revision);
7885         offset += 1;
7886
7887         /* next byte should be zero, for now just ignore it */
7888         offset += 1;
7889
7890
7891         switch(revision){
7892         case 1:  /* only version we will ever see of this structure?*/
7893           /* type */
7894           offset = dissect_nt_sec_desc_type(tvb, offset, tree);
7895
7896           /* offset to owner sid */
7897           owner_sid_offset = tvb_get_letohl(tvb, offset);
7898           proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %u", owner_sid_offset);
7899           offset += 4;
7900
7901           /* offset to group sid */
7902           group_sid_offset = tvb_get_letohl(tvb, offset);
7903           proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %u", group_sid_offset);
7904           offset += 4;
7905
7906           /* offset to sacl */
7907           sacl_offset = tvb_get_letohl(tvb, offset);
7908           proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %u", sacl_offset);
7909           offset += 4;
7910
7911           /* offset to dacl */
7912           dacl_offset = tvb_get_letohl(tvb, offset);
7913           proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %u", dacl_offset);
7914           offset += 4;
7915
7916           /*owner SID*/
7917           if(owner_sid_offset){
7918             if (len == -1)
7919               offset = dissect_nt_sid(tvb, offset, tree, "Owner", NULL, -1);
7920             else
7921               dissect_nt_sid(
7922                       tvb, old_offset+owner_sid_offset, tree, "Owner", NULL, -1);
7923           }
7924
7925           /*group SID*/
7926           if(group_sid_offset){
7927             dissect_nt_sid(
7928                     tvb, old_offset+group_sid_offset, tree, "Group", NULL, -1);
7929           }
7930
7931           /* sacl */
7932           if(sacl_offset){
7933             dissect_nt_acl(tvb, old_offset+sacl_offset, pinfo, tree, 
7934                            drep, "System (SACL)", ami);
7935           }
7936
7937           /* dacl */
7938           if(dacl_offset){
7939             dissect_nt_acl(tvb, old_offset+dacl_offset, pinfo, tree, 
7940                            drep, "User (DACL)", ami);
7941           }
7942
7943         }
7944
7945         return offset+len;
7946 }
7947
7948 static int
7949 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
7950 {
7951         int old_offset, old_sid_offset;
7952         guint32 qsize;
7953
7954         do {
7955                 old_offset=offset;
7956
7957                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7958                 qsize=tvb_get_letohl(tvb, offset);
7959                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
7960                 COUNT_BYTES_TRANS_SUBR(4);
7961
7962                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7963                 /* length of SID */
7964                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7965                 COUNT_BYTES_TRANS_SUBR(4);
7966
7967                 /* 16 unknown bytes */
7968                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7969                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7970                             offset, 8, TRUE);
7971                 COUNT_BYTES_TRANS_SUBR(8);
7972
7973                 /* number of bytes for used quota */
7974                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7975                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
7976                 COUNT_BYTES_TRANS_SUBR(8);
7977
7978                 /* number of bytes for quota warning */
7979                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7980                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
7981                 COUNT_BYTES_TRANS_SUBR(8);
7982
7983                 /* number of bytes for quota limit */
7984                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7985                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
7986                 COUNT_BYTES_TRANS_SUBR(8);
7987
7988                 /* SID of the user */
7989                 old_sid_offset=offset;
7990                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
7991                 *bcp -= (offset-old_sid_offset);
7992
7993                 if(qsize){
7994                         offset = old_offset+qsize;
7995                 }
7996         }while(qsize);
7997
7998
7999         return offset;
8000 }
8001
8002
8003 static int
8004 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
8005 {
8006         proto_item *item = NULL;
8007         proto_tree *tree = NULL;
8008         smb_info_t *si;
8009         int old_offset = offset;
8010         guint16 bcp=bc; /* XXX fixme */
8011
8012         si = (smb_info_t *)pinfo->private_data;
8013
8014         if(parent_tree){
8015                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
8016                                 "%s Data",
8017                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8018                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8019         }
8020
8021         switch(ntd->subcmd){
8022         case NT_TRANS_CREATE:
8023                 /* security descriptor */
8024                 if(ntd->sd_len){
8025                         offset = dissect_nt_sec_desc(
8026                                 tvb, offset, pinfo, tree, NULL, ntd->sd_len, 
8027                                 NULL);
8028                 }
8029
8030                 /* extended attributes */
8031                 if(ntd->ea_len){
8032                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
8033                         offset += ntd->ea_len;
8034                 }
8035
8036                 break;
8037         case NT_TRANS_IOCTL:
8038                 /* ioctl data */
8039                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
8040                 offset += bc;
8041
8042                 break;
8043         case NT_TRANS_SSD:
8044                 offset = dissect_nt_sec_desc(
8045                         tvb, offset, pinfo, tree, NULL, bc, NULL);
8046                 break;
8047         case NT_TRANS_NOTIFY:
8048                 break;
8049         case NT_TRANS_RENAME:
8050                 /* XXX not documented */
8051                 break;
8052         case NT_TRANS_QSD:
8053                 break;
8054         case NT_TRANS_GET_USER_QUOTA:
8055                 /* unknown 4 bytes */
8056                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8057                             offset, 4, TRUE);
8058                 offset += 4;
8059
8060                 /* length of SID */
8061                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
8062                 offset +=4;
8063
8064                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8065                 break;
8066         case NT_TRANS_SET_USER_QUOTA:
8067                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8068                 break;
8069         }
8070
8071         /* ooops there were data we didnt know how to process */
8072         if((offset-old_offset) < bc){
8073                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
8074                     bc - (offset-old_offset), TRUE);
8075                 offset += bc - (offset-old_offset);
8076         }
8077
8078         return offset;
8079 }
8080
8081 static int
8082 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)
8083 {
8084         proto_item *item = NULL;
8085         proto_tree *tree = NULL;
8086         smb_info_t *si;
8087         guint32 fn_len;
8088         const char *fn;
8089
8090         si = (smb_info_t *)pinfo->private_data;
8091
8092         if(parent_tree){
8093                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8094                                 "%s Parameters",
8095                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8096                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8097         }
8098
8099         switch(ntd->subcmd){
8100         case NT_TRANS_CREATE:
8101                 /* Create flags */
8102                 offset = dissect_nt_create_bits(tvb, tree, offset);
8103                 bc -= 4;
8104
8105                 /* root directory fid */
8106                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
8107                 COUNT_BYTES(4);
8108
8109                 /* nt access mask */
8110                 offset = dissect_smb_access_mask(tvb, tree, offset);
8111                 bc -= 4;
8112
8113                 /* allocation size */
8114                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8115                 COUNT_BYTES(8);
8116
8117                 /* Extended File Attributes */
8118                 offset = dissect_file_ext_attr(tvb, tree, offset);
8119                 bc -= 4;
8120
8121                 /* share access */
8122                 offset = dissect_nt_share_access(tvb, tree, offset);
8123                 bc -= 4;
8124
8125                 /* create disposition */
8126                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8127                 COUNT_BYTES(4);
8128
8129                 /* create options */
8130                 offset = dissect_nt_create_options(tvb, tree, offset);
8131                 bc -= 4;
8132
8133                 /* sd length */
8134                 ntd->sd_len = tvb_get_letohl(tvb, offset);
8135                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
8136                 COUNT_BYTES(4);
8137
8138                 /* ea length */
8139                 ntd->ea_len = tvb_get_letohl(tvb, offset);
8140                 proto_tree_add_uint(tree, hf_smb_ea_list_length, tvb, offset, 4, ntd->ea_len);
8141                 COUNT_BYTES(4);
8142
8143                 /* file name len */
8144                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
8145                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8146                 COUNT_BYTES(4);
8147
8148                 /* impersonation level */
8149                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8150                 COUNT_BYTES(4);
8151
8152                 /* security flags */
8153                 offset = dissect_nt_security_flags(tvb, tree, offset);
8154                 bc -= 1;
8155
8156                 /* file name */
8157                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8158                 if (fn != NULL) {
8159                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8160                                 fn);
8161                         COUNT_BYTES(fn_len);
8162                 }
8163
8164                 break;
8165         case NT_TRANS_IOCTL:
8166                 break;
8167         case NT_TRANS_SSD: {
8168                 guint16 fid;
8169
8170                 /* fid */
8171                 fid = tvb_get_letohs(tvb, offset);
8172                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8173                 offset += 2;
8174
8175                 /* 2 reserved bytes */
8176                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8177                 offset += 2;
8178
8179                 /* security information */
8180                 offset = dissect_security_information_mask(tvb, tree, offset);
8181                 break;
8182         }
8183         case NT_TRANS_NOTIFY:
8184                 break;
8185         case NT_TRANS_RENAME:
8186                 /* XXX not documented */
8187                 break;
8188         case NT_TRANS_QSD: {
8189                 guint16 fid;
8190
8191                 /* fid */
8192                 fid = tvb_get_letohs(tvb, offset);
8193                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8194                 offset += 2;
8195
8196                 /* 2 reserved bytes */
8197                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8198                 offset += 2;
8199
8200                 /* security information */
8201                 offset = dissect_security_information_mask(tvb, tree, offset);
8202                 break;
8203         }
8204         case NT_TRANS_GET_USER_QUOTA:
8205                 /* not decoded yet */
8206                 break;
8207         case NT_TRANS_SET_USER_QUOTA:
8208                 /* not decoded yet */
8209                 break;
8210         }
8211
8212         return offset;
8213 }
8214
8215 static int
8216 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
8217 {
8218         proto_item *item = NULL;
8219         proto_tree *tree = NULL;
8220         smb_info_t *si;
8221         int old_offset = offset;
8222
8223         si = (smb_info_t *)pinfo->private_data;
8224
8225         if(parent_tree){
8226                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8227                                 "%s Setup",
8228                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8229                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8230         }
8231
8232         switch(ntd->subcmd){
8233         case NT_TRANS_CREATE:
8234                 break;
8235         case NT_TRANS_IOCTL: {
8236                 guint16 fid;
8237
8238                 /* function code */
8239                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
8240                 offset += 4;
8241
8242                 /* fid */
8243                 fid = tvb_get_letohs(tvb, offset);
8244                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8245                 offset += 2;
8246
8247                 /* isfsctl */
8248                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
8249                 offset += 1;
8250
8251                 /* isflags */
8252                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
8253
8254                 break;
8255         }
8256         case NT_TRANS_SSD:
8257                 break;
8258         case NT_TRANS_NOTIFY: {
8259                 guint16 fid;
8260
8261                 /* completion filter */
8262                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
8263
8264                 /* fid */
8265                 fid = tvb_get_letohs(tvb, offset);
8266                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8267                 offset += 2;
8268
8269                 /* watch tree */
8270                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
8271                 offset += 1;
8272
8273                 /* reserved byte */
8274                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8275                 offset += 1;
8276
8277                 break;
8278         }
8279         case NT_TRANS_RENAME:
8280                 /* XXX not documented */
8281                 break;
8282         case NT_TRANS_QSD:
8283                 break;
8284         case NT_TRANS_GET_USER_QUOTA:
8285                 /* not decoded yet */
8286                 break;
8287         case NT_TRANS_SET_USER_QUOTA:
8288                 /* not decoded yet */
8289                 break;
8290         }
8291
8292         return old_offset+len;
8293 }
8294
8295
8296 static int
8297 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8298 {
8299         guint8 wc, sc;
8300         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
8301         smb_info_t *si;
8302         smb_saved_info_t *sip;
8303         int subcmd;
8304         nt_trans_data ntd;
8305         guint16 bc;
8306         int padcnt;
8307         smb_nt_transact_info_t *nti;
8308
8309         si = (smb_info_t *)pinfo->private_data;
8310         sip = si->sip;
8311
8312         WORD_COUNT;
8313
8314         if(wc>=19){
8315                 /* primary request */
8316                 /* max setup count */
8317                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
8318                 offset += 1;
8319
8320                 /* 2 reserved bytes */
8321                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8322                 offset += 2;
8323         } else {
8324                 /* secondary request */
8325                 /* 3 reserved bytes */
8326                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8327                 offset += 3;
8328         }
8329
8330
8331         /* total param count */
8332         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
8333         offset += 4;
8334
8335         /* total data count */
8336         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
8337         offset += 4;
8338
8339         if(wc>=19){
8340                 /* primary request */
8341                 /* max param count */
8342                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
8343                 offset += 4;
8344
8345                 /* max data count */
8346                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
8347                 offset += 4;
8348         }
8349
8350         /* param count */
8351         pc = tvb_get_letohl(tvb, offset);
8352         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8353         offset += 4;
8354
8355         /* param offset */
8356         po = tvb_get_letohl(tvb, offset);
8357         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8358         offset += 4;
8359
8360         /* param displacement */
8361         if(wc>=19){
8362                 /* primary request*/
8363                 pd = 0;
8364         } else {
8365                 /* secondary request */
8366                 pd = tvb_get_letohl(tvb, offset);
8367                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8368                 offset += 4;
8369         }
8370
8371         /* data count */
8372         dc = tvb_get_letohl(tvb, offset);
8373         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8374         offset += 4;
8375
8376         /* data offset */
8377         od = tvb_get_letohl(tvb, offset);
8378         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8379         offset += 4;
8380
8381         /* data displacement */
8382         if(wc>=19){
8383                 /* primary request */
8384                 dd = 0;
8385         } else {
8386                 /* secondary request */
8387                 dd = tvb_get_letohl(tvb, offset);
8388                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8389                 offset += 4;
8390         }
8391
8392         /* setup count */
8393         if(wc>=19){
8394                 /* primary request */
8395                 sc = tvb_get_guint8(tvb, offset);
8396                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8397                 offset += 1;
8398         } else {
8399                 /* secondary request */
8400                 sc = 0;
8401         }
8402
8403         /* function */
8404         if(wc>=19){
8405                 /* primary request */
8406                 subcmd = tvb_get_letohs(tvb, offset);
8407                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
8408                 if(check_col(pinfo->cinfo, COL_INFO)){
8409                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8410                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
8411                 }
8412                 ntd.subcmd = subcmd;
8413                 if (!si->unidir) {
8414                         if(!pinfo->fd->flags.visited){
8415                                 /*
8416                                  * Allocate a new smb_nt_transact_info_t
8417                                  * structure.
8418                                  */
8419                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
8420                                 nti->subcmd = subcmd;
8421                                 sip->extra_info = nti;
8422                         }
8423                 }
8424         } else {
8425                 /* secondary request */
8426                 if(check_col(pinfo->cinfo, COL_INFO)){
8427                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
8428                 }
8429         }
8430         offset += 2;
8431
8432         /* this is a padding byte */
8433         if(offset%1){
8434                 /* pad byte */
8435                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
8436                 offset += 1;
8437         }
8438
8439         /* if there were any setup bytes, decode them */
8440         if(sc){
8441                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
8442                 offset += sc*2;
8443         }
8444
8445         BYTE_COUNT;
8446
8447         /* parameters */
8448         if(po>(guint32)offset){
8449                 /* We have some initial padding bytes.
8450                 */
8451                 padcnt = po-offset;
8452                 if (padcnt > bc)
8453                         padcnt = bc;
8454                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8455                 COUNT_BYTES(padcnt);
8456         }
8457         if(pc){
8458                 CHECK_BYTE_COUNT(pc);
8459                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
8460                 COUNT_BYTES(pc);
8461         }
8462
8463         /* data */
8464         if(od>(guint32)offset){
8465                 /* We have some initial padding bytes.
8466                 */
8467                 padcnt = od-offset;
8468                 if (padcnt > bc)
8469                         padcnt = bc;
8470                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8471                 COUNT_BYTES(padcnt);
8472         }
8473         if(dc){
8474                 CHECK_BYTE_COUNT(dc);
8475                 dissect_nt_trans_data_request(
8476                         tvb, pinfo, offset, tree, dc, &ntd);
8477                 COUNT_BYTES(dc);
8478         }
8479
8480         END_OF_SMB
8481
8482         return offset;
8483 }
8484
8485
8486
8487 static int
8488 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
8489                                int offset, proto_tree *parent_tree, int len,
8490                                nt_trans_data *ntd _U_)
8491 {
8492         proto_item *item = NULL;
8493         proto_tree *tree = NULL;
8494         smb_info_t *si;
8495         smb_nt_transact_info_t *nti;
8496         guint16 bcp;
8497
8498         si = (smb_info_t *)pinfo->private_data;
8499         if (si->sip != NULL)
8500                 nti = si->sip->extra_info;
8501         else
8502                 nti = NULL;
8503
8504         if(parent_tree){
8505                 if(nti != NULL){
8506                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8507                                 "%s Data",
8508                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8509                 } else {
8510                         /*
8511                          * We never saw the request to which this is a
8512                          * response.
8513                          */
8514                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8515                                 "Unknown NT Transaction Data (matching request not seen)");
8516                 }
8517                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8518         }
8519
8520         if (nti == NULL) {
8521                 offset += len;
8522                 return offset;
8523         }
8524         switch(nti->subcmd){
8525         case NT_TRANS_CREATE:
8526                 break;
8527         case NT_TRANS_IOCTL:
8528                 /* ioctl data */
8529                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
8530                 offset += len;
8531
8532                 break;
8533         case NT_TRANS_SSD:
8534                 break;
8535         case NT_TRANS_NOTIFY:
8536                 break;
8537         case NT_TRANS_RENAME:
8538                 /* XXX not documented */
8539                 break;
8540         case NT_TRANS_QSD: {
8541                 /*
8542                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
8543                  * which may be documented in the Win32 documentation
8544                  * somewhere.
8545                  */
8546                 offset = dissect_nt_sec_desc(
8547                         tvb, offset, pinfo, tree, NULL, len, NULL);
8548                 break;
8549         }
8550         case NT_TRANS_GET_USER_QUOTA:
8551                 bcp=len;
8552                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8553                 break;
8554         case NT_TRANS_SET_USER_QUOTA:
8555                 /* not decoded yet */
8556                 break;
8557         }
8558
8559         return offset;
8560 }
8561
8562 static int
8563 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
8564                                 int offset, proto_tree *parent_tree,
8565                                 int len, nt_trans_data *ntd _U_, guint16 bc)
8566 {
8567         proto_item *item = NULL;
8568         proto_tree *tree = NULL;
8569         guint32 fn_len;
8570         const char *fn;
8571         smb_info_t *si;
8572         smb_nt_transact_info_t *nti;
8573         guint16 fid;
8574         int old_offset;
8575         guint32 neo;
8576         int padcnt;
8577
8578         si = (smb_info_t *)pinfo->private_data;
8579         if (si->sip != NULL)
8580                 nti = si->sip->extra_info;
8581         else
8582                 nti = NULL;
8583
8584         if(parent_tree){
8585                 if(nti != NULL){
8586                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8587                                 "%s Parameters",
8588                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8589                 } else {
8590                         /*
8591                          * We never saw the request to which this is a
8592                          * response.
8593                          */
8594                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8595                                 "Unknown NT Transaction Parameters (matching request not seen)");
8596                 }
8597                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8598         }
8599
8600         if (nti == NULL) {
8601                 offset += len;
8602                 return offset;
8603         }
8604         switch(nti->subcmd){
8605         case NT_TRANS_CREATE:
8606                 /* oplock level */
8607                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8608                 offset += 1;
8609
8610                 /* reserved byte */
8611                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8612                 offset += 1;
8613
8614                 /* fid */
8615                 fid = tvb_get_letohs(tvb, offset);
8616                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8617                 offset += 2;
8618
8619                 /* create action */
8620                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8621                 offset += 4;
8622
8623                 /* ea error offset */
8624                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
8625                 offset += 4;
8626
8627                 /* create time */
8628                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8629                         hf_smb_create_time);
8630
8631                 /* access time */
8632                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8633                         hf_smb_access_time);
8634
8635                 /* last write time */
8636                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8637                         hf_smb_last_write_time);
8638
8639                 /* last change time */
8640                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8641                         hf_smb_change_time);
8642
8643                 /* Extended File Attributes */
8644                 offset = dissect_file_ext_attr(tvb, tree, offset);
8645
8646                 /* allocation size */
8647                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8648                 offset += 8;
8649
8650                 /* end of file */
8651                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8652                 offset += 8;
8653
8654                 /* File Type */
8655                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8656                 offset += 2;
8657
8658                 /* device state */
8659                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8660
8661                 /* is directory */
8662                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8663                 offset += 1;
8664                 break;
8665         case NT_TRANS_IOCTL:
8666                 break;
8667         case NT_TRANS_SSD:
8668                 break;
8669         case NT_TRANS_NOTIFY:
8670                 while(len){
8671                         old_offset = offset;
8672
8673                         /* next entry offset */
8674                         neo = tvb_get_letohl(tvb, offset);
8675                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8676                         COUNT_BYTES(4);
8677                         len -= 4;
8678                         /* broken implementations */
8679                         if(len<0)break;
8680
8681                         /* action */
8682                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
8683                         COUNT_BYTES(4);
8684                         len -= 4;
8685                         /* broken implementations */
8686                         if(len<0)break;
8687
8688                         /* file name len */
8689                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
8690                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8691                         COUNT_BYTES(4);
8692                         len -= 4;
8693                         /* broken implementations */
8694                         if(len<0)break;
8695
8696                         /* file name */
8697                         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8698                         if (fn == NULL)
8699                                 break;
8700                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8701                                 fn);
8702                         COUNT_BYTES(fn_len);
8703                         len -= fn_len;
8704                         /* broken implementations */
8705                         if(len<0)break;
8706
8707                         if (neo == 0)
8708                                 break;  /* no more structures */
8709
8710                         /* skip to next structure */
8711                         padcnt = (old_offset + neo) - offset;
8712                         if (padcnt < 0) {
8713                                 /*
8714                                  * XXX - this is bogus; flag it?
8715                                  */
8716                                 padcnt = 0;
8717                         }
8718                         if (padcnt != 0) {
8719                                 COUNT_BYTES(padcnt);
8720                                 len -= padcnt;
8721                                 /* broken implementations */
8722                                 if(len<0)break;
8723                         }
8724                 }
8725                 break;
8726         case NT_TRANS_RENAME:
8727                 /* XXX not documented */
8728                 break;
8729         case NT_TRANS_QSD:
8730                 /*
8731                  * This appears to be the size of the security
8732                  * descriptor; the calling sequence of
8733                  * "ZwQuerySecurityObject()" suggests that it would
8734                  * be.  The actual security descriptor wouldn't
8735                  * follow if the max data count in the request
8736                  * was smaller; this lets the client know how
8737                  * big a buffer it needs to provide.
8738                  */
8739                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
8740                 offset += 4;
8741                 break;
8742         case NT_TRANS_GET_USER_QUOTA:
8743                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
8744                         tvb_get_letohl(tvb, offset));
8745                 offset += 4;
8746                 break;
8747         case NT_TRANS_SET_USER_QUOTA:
8748                 /* not decoded yet */
8749                 break;
8750         }
8751
8752         return offset;
8753 }
8754
8755 static int
8756 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
8757                                 int offset, proto_tree *parent_tree,
8758                                 int len, nt_trans_data *ntd _U_)
8759 {
8760         proto_item *item = NULL;
8761         proto_tree *tree = NULL;
8762         smb_info_t *si;
8763         smb_nt_transact_info_t *nti;
8764
8765         si = (smb_info_t *)pinfo->private_data;
8766         if (si->sip != NULL)
8767                 nti = si->sip->extra_info;
8768         else
8769                 nti = NULL;
8770
8771         if(parent_tree){
8772                 if(nti != NULL){
8773                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8774                                 "%s Setup",
8775                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8776                 } else {
8777                         /*
8778                          * We never saw the request to which this is a
8779                          * response.
8780                          */
8781                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8782                                 "Unknown NT Transaction Setup (matching request not seen)");
8783                 }
8784                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8785         }
8786
8787         if (nti == NULL) {
8788                 offset += len;
8789                 return offset;
8790         }
8791         switch(nti->subcmd){
8792         case NT_TRANS_CREATE:
8793                 break;
8794         case NT_TRANS_IOCTL:
8795                 break;
8796         case NT_TRANS_SSD:
8797                 break;
8798         case NT_TRANS_NOTIFY:
8799                 break;
8800         case NT_TRANS_RENAME:
8801                 /* XXX not documented */
8802                 break;
8803         case NT_TRANS_QSD:
8804                 break;
8805         case NT_TRANS_GET_USER_QUOTA:
8806                 /* not decoded yet */
8807                 break;
8808         case NT_TRANS_SET_USER_QUOTA:
8809                 /* not decoded yet */
8810                 break;
8811         }
8812
8813         return offset;
8814 }
8815
8816 static int
8817 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8818 {
8819         guint8 wc, sc;
8820         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
8821         guint32 td=0, tp=0;
8822         smb_info_t *si;
8823         smb_nt_transact_info_t *nti;
8824         static nt_trans_data ntd;
8825         guint16 bc;
8826         int padcnt;
8827         fragment_data *r_fd = NULL;
8828         tvbuff_t *pd_tvb=NULL;
8829         gboolean save_fragmented;
8830
8831         si = (smb_info_t *)pinfo->private_data;
8832         if (si->sip != NULL)
8833                 nti = si->sip->extra_info;
8834         else
8835                 nti = NULL;
8836
8837         /* primary request */
8838         if(nti != NULL){
8839                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
8840                 if(check_col(pinfo->cinfo, COL_INFO)){
8841                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8842                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
8843                 }
8844         } else {
8845                 proto_tree_add_text(tree, tvb, offset, 0,
8846                         "Function: <unknown function - could not find matching request>");
8847                 if(check_col(pinfo->cinfo, COL_INFO)){
8848                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
8849                 }
8850         }
8851
8852         WORD_COUNT;
8853
8854         /* 3 reserved bytes */
8855         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8856         offset += 3;
8857
8858         /* total param count */
8859         tp = tvb_get_letohl(tvb, offset);
8860         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8861         offset += 4;
8862
8863         /* total data count */
8864         td = tvb_get_letohl(tvb, offset);
8865         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8866         offset += 4;
8867
8868         /* param count */
8869         pc = tvb_get_letohl(tvb, offset);
8870         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8871         offset += 4;
8872
8873         /* param offset */
8874         po = tvb_get_letohl(tvb, offset);
8875         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8876         offset += 4;
8877
8878         /* param displacement */
8879         pd = tvb_get_letohl(tvb, offset);
8880         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8881         offset += 4;
8882
8883         /* data count */
8884         dc = tvb_get_letohl(tvb, offset);
8885         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8886         offset += 4;
8887
8888         /* data offset */
8889         od = tvb_get_letohl(tvb, offset);
8890         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8891         offset += 4;
8892
8893         /* data displacement */
8894         dd = tvb_get_letohl(tvb, offset);
8895         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8896         offset += 4;
8897
8898         /* setup count */
8899         sc = tvb_get_guint8(tvb, offset);
8900         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8901         offset += 1;
8902
8903         /* setup data */
8904         if(sc){
8905                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
8906                 offset += sc*2;
8907         }
8908
8909         BYTE_COUNT;
8910
8911         /* reassembly of SMB NT Transaction data payload.
8912            In this section we do reassembly of both the data and parameters
8913            blocks of the SMB transaction command.
8914         */
8915         save_fragmented = pinfo->fragmented;
8916         /* do we need reassembly? */
8917         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
8918                 /* oh yeah, either data or parameter section needs
8919                    reassembly...
8920                 */
8921                 pinfo->fragmented = TRUE;
8922                 if(smb_trans_reassembly){
8923                         /* ...and we were told to do reassembly */
8924                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
8925                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8926                                                              po, pc, pd, td+tp);
8927
8928                         }
8929                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
8930                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8931                                                              od, dc, dd+tp, td+tp);
8932                         }
8933                 }
8934         }
8935
8936         /* if we got a reassembled fd structure from the reassembly routine we
8937            must create pd_tvb from it
8938         */
8939         if(r_fd){
8940                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
8941                                              r_fd->datalen);
8942                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
8943                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
8944
8945                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
8946         }
8947
8948
8949         if(pd_tvb){
8950           /* we have reassembled data, grab param and data from there */
8951           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
8952                                           &ntd, tvb_length(pd_tvb));
8953           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
8954         } else {
8955           /* we do not have reassembled data, just use what we have in the
8956              packet as well as we can */
8957           /* parameters */
8958           if(po>(guint32)offset){
8959             /* We have some initial padding bytes.
8960              */
8961             padcnt = po-offset;
8962             if (padcnt > bc)
8963               padcnt = bc;
8964             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8965             COUNT_BYTES(padcnt);
8966           }
8967           if(pc){
8968             CHECK_BYTE_COUNT(pc);
8969             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
8970             COUNT_BYTES(pc);
8971           }
8972
8973           /* data */
8974           if(od>(guint32)offset){
8975             /* We have some initial padding bytes.
8976              */
8977             padcnt = od-offset;
8978             if (padcnt > bc)
8979               padcnt = bc;
8980             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8981             COUNT_BYTES(padcnt);
8982           }
8983           if(dc){
8984             CHECK_BYTE_COUNT(dc);
8985             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
8986             COUNT_BYTES(dc);
8987           }
8988         }
8989         pinfo->fragmented = save_fragmented;
8990
8991         END_OF_SMB
8992
8993         return offset;
8994 }
8995
8996 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8997    NT Transaction command  ends here
8998    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8999
9000 static const value_string print_mode_vals[] = {
9001         {0,     "Text Mode"},
9002         {1,     "Graphics Mode"},
9003         {0, NULL}
9004 };
9005
9006 static int
9007 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9008 {
9009         smb_info_t *si = pinfo->private_data;
9010         int fn_len;
9011         const char *fn;
9012         guint8 wc;
9013         guint16 bc;
9014
9015         WORD_COUNT;
9016
9017         /* setup len */
9018         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
9019         offset += 2;
9020
9021         /* print mode */
9022         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
9023         offset += 2;
9024
9025         BYTE_COUNT;
9026
9027         /* buffer format */
9028         CHECK_BYTE_COUNT(1);
9029         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9030         COUNT_BYTES(1);
9031
9032         /* print identifier */
9033         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
9034         if (fn == NULL)
9035                 goto endofcommand;
9036         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
9037                 fn);
9038         COUNT_BYTES(fn_len);
9039
9040         END_OF_SMB
9041
9042         return offset;
9043 }
9044
9045
9046 static int
9047 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9048 {
9049         int cnt;
9050         guint8 wc;
9051         guint16 bc, fid;
9052
9053         WORD_COUNT;
9054
9055         /* fid */
9056         fid = tvb_get_letohs(tvb, offset);
9057         add_fid(tvb, pinfo, tree, offset, 2, fid);
9058         offset += 2;
9059
9060         BYTE_COUNT;
9061
9062         /* buffer format */
9063         CHECK_BYTE_COUNT(1);
9064         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9065         COUNT_BYTES(1);
9066
9067         /* data len */
9068         CHECK_BYTE_COUNT(2);
9069         cnt = tvb_get_letohs(tvb, offset);
9070         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
9071         COUNT_BYTES(2);
9072
9073         /* file data */
9074         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
9075
9076         END_OF_SMB
9077
9078         return offset;
9079 }
9080
9081
9082 static const value_string print_status_vals[] = {
9083         {1,     "Held or Stopped"},
9084         {2,     "Printing"},
9085         {3,     "Awaiting print"},
9086         {4,     "In intercept"},
9087         {5,     "File had error"},
9088         {6,     "Printer error"},
9089         {0, NULL}
9090 };
9091
9092 static int
9093 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9094 {
9095         guint8 wc;
9096         guint16 bc;
9097
9098         WORD_COUNT;
9099
9100         /* max count */
9101         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
9102         offset += 2;
9103
9104         /* start index */
9105         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
9106         offset += 2;
9107
9108         BYTE_COUNT;
9109
9110         END_OF_SMB
9111
9112         return offset;
9113 }
9114
9115 static int
9116 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
9117     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
9118 {
9119         proto_item *item = NULL;
9120         proto_tree *tree = NULL;
9121         smb_info_t *si = pinfo->private_data;
9122         int fn_len;
9123         const char *fn;
9124
9125         if(parent_tree){
9126                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
9127                         "Queue entry");
9128                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
9129         }
9130
9131         /* queued time */
9132         CHECK_BYTE_COUNT_SUBR(4);
9133         offset = dissect_smb_datetime(tvb, tree, offset,
9134                 hf_smb_print_queue_date,
9135                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
9136         *bcp -= 4;
9137
9138         /* status */
9139         CHECK_BYTE_COUNT_SUBR(1);
9140         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
9141         COUNT_BYTES_SUBR(1);
9142
9143         /* spool file number */
9144         CHECK_BYTE_COUNT_SUBR(2);
9145         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
9146         COUNT_BYTES_SUBR(2);
9147
9148         /* spool file size */
9149         CHECK_BYTE_COUNT_SUBR(4);
9150         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
9151         COUNT_BYTES_SUBR(4);
9152
9153         /* reserved byte */
9154         CHECK_BYTE_COUNT_SUBR(1);
9155         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9156         COUNT_BYTES_SUBR(1);
9157
9158         /* file name */
9159         fn_len = 16;
9160         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
9161         CHECK_STRING_SUBR(fn);
9162         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
9163                 fn);
9164         COUNT_BYTES_SUBR(fn_len);
9165
9166         *trunc = FALSE;
9167         return offset;
9168 }
9169
9170 static int
9171 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9172 {
9173         guint16 cnt=0, len;
9174         guint8 wc;
9175         guint16 bc;
9176         gboolean trunc;
9177
9178         WORD_COUNT;
9179
9180         /* count */
9181         cnt = tvb_get_letohs(tvb, offset);
9182         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
9183         offset += 2;
9184
9185         /* restart index */
9186         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
9187         offset += 2;
9188
9189         BYTE_COUNT;
9190
9191         /* buffer format */
9192         CHECK_BYTE_COUNT(1);
9193         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9194         COUNT_BYTES(1);
9195
9196         /* data len */
9197         CHECK_BYTE_COUNT(2);
9198         len = tvb_get_letohs(tvb, offset);
9199         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
9200         COUNT_BYTES(2);
9201
9202         /* queue elements */
9203         while(cnt--){
9204                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
9205                     &bc, &trunc);
9206                 if (trunc)
9207                         goto endofcommand;
9208         }
9209
9210         END_OF_SMB
9211
9212         return offset;
9213 }
9214
9215
9216 static int
9217 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9218 {
9219         int name_len;
9220         guint16 bc;
9221         guint8 wc;
9222         guint16 message_len;
9223
9224         WORD_COUNT;
9225
9226         BYTE_COUNT;
9227
9228         /* buffer format */
9229         CHECK_BYTE_COUNT(1);
9230         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9231         COUNT_BYTES(1);
9232
9233         /* originator name */
9234         /* XXX - what if this runs past bc? */
9235         name_len = tvb_strsize(tvb, offset);
9236         CHECK_BYTE_COUNT(name_len);
9237         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9238             name_len, TRUE);
9239         COUNT_BYTES(name_len);
9240
9241         /* buffer format */
9242         CHECK_BYTE_COUNT(1);
9243         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9244         COUNT_BYTES(1);
9245
9246         /* destination name */
9247         /* XXX - what if this runs past bc? */
9248         name_len = tvb_strsize(tvb, offset);
9249         CHECK_BYTE_COUNT(name_len);
9250         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9251             name_len, TRUE);
9252         COUNT_BYTES(name_len);
9253
9254         /* buffer format */
9255         CHECK_BYTE_COUNT(1);
9256         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9257         COUNT_BYTES(1);
9258
9259         /* message len */
9260         CHECK_BYTE_COUNT(2);
9261         message_len = tvb_get_letohs(tvb, offset);
9262         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9263             message_len);
9264         COUNT_BYTES(2);
9265
9266         /* message */
9267         CHECK_BYTE_COUNT(message_len);
9268         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9269             TRUE);
9270         COUNT_BYTES(message_len);
9271
9272         END_OF_SMB
9273
9274         return offset;
9275 }
9276
9277 static int
9278 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9279 {
9280         int name_len;
9281         guint16 bc;
9282         guint8 wc;
9283
9284         WORD_COUNT;
9285
9286         BYTE_COUNT;
9287
9288         /* buffer format */
9289         CHECK_BYTE_COUNT(1);
9290         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9291         COUNT_BYTES(1);
9292
9293         /* originator name */
9294         /* XXX - what if this runs past bc? */
9295         name_len = tvb_strsize(tvb, offset);
9296         CHECK_BYTE_COUNT(name_len);
9297         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9298             name_len, TRUE);
9299         COUNT_BYTES(name_len);
9300
9301         /* buffer format */
9302         CHECK_BYTE_COUNT(1);
9303         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9304         COUNT_BYTES(1);
9305
9306         /* destination name */
9307         /* XXX - what if this runs past bc? */
9308         name_len = tvb_strsize(tvb, offset);
9309         CHECK_BYTE_COUNT(name_len);
9310         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9311             name_len, TRUE);
9312         COUNT_BYTES(name_len);
9313
9314         END_OF_SMB
9315
9316         return offset;
9317 }
9318
9319 static int
9320 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9321 {
9322         guint16 bc;
9323         guint8 wc;
9324
9325         WORD_COUNT;
9326
9327         /* message group ID */
9328         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
9329         offset += 2;
9330
9331         BYTE_COUNT;
9332
9333         END_OF_SMB
9334
9335         return offset;
9336 }
9337
9338 static int
9339 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9340 {
9341         guint16 bc;
9342         guint8 wc;
9343         guint16 message_len;
9344
9345         WORD_COUNT;
9346
9347         BYTE_COUNT;
9348
9349         /* buffer format */
9350         CHECK_BYTE_COUNT(1);
9351         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9352         COUNT_BYTES(1);
9353
9354         /* message len */
9355         CHECK_BYTE_COUNT(2);
9356         message_len = tvb_get_letohs(tvb, offset);
9357         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9358             message_len);
9359         COUNT_BYTES(2);
9360
9361         /* message */
9362         CHECK_BYTE_COUNT(message_len);
9363         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9364             TRUE);
9365         COUNT_BYTES(message_len);
9366
9367         END_OF_SMB
9368
9369         return offset;
9370 }
9371
9372 static int
9373 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9374 {
9375         int name_len;
9376         guint16 bc;
9377         guint8 wc;
9378
9379         WORD_COUNT;
9380
9381         BYTE_COUNT;
9382
9383         /* buffer format */
9384         CHECK_BYTE_COUNT(1);
9385         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9386         COUNT_BYTES(1);
9387
9388         /* forwarded name */
9389         /* XXX - what if this runs past bc? */
9390         name_len = tvb_strsize(tvb, offset);
9391         CHECK_BYTE_COUNT(name_len);
9392         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
9393             name_len, TRUE);
9394         COUNT_BYTES(name_len);
9395
9396         END_OF_SMB
9397
9398         return offset;
9399 }
9400
9401 static int
9402 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9403 {
9404         int name_len;
9405         guint16 bc;
9406         guint8 wc;
9407
9408         WORD_COUNT;
9409
9410         BYTE_COUNT;
9411
9412         /* buffer format */
9413         CHECK_BYTE_COUNT(1);
9414         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9415         COUNT_BYTES(1);
9416
9417         /* machine name */
9418         /* XXX - what if this runs past bc? */
9419         name_len = tvb_strsize(tvb, offset);
9420         CHECK_BYTE_COUNT(name_len);
9421         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
9422             name_len, TRUE);
9423         COUNT_BYTES(name_len);
9424
9425         END_OF_SMB
9426
9427         return offset;
9428 }
9429
9430
9431 static int
9432 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9433 {
9434         guint8  wc, cmd=0xff;
9435         guint16 andxoffset=0;
9436         guint16 bc;
9437         smb_info_t *si = pinfo->private_data;
9438         int fn_len;
9439         const char *fn;
9440
9441         WORD_COUNT;
9442
9443         /* next smb command */
9444         cmd = tvb_get_guint8(tvb, offset);
9445         if(cmd!=0xff){
9446                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9447         } else {
9448                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9449         }
9450         offset += 1;
9451
9452         /* reserved byte */
9453         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9454         offset += 1;
9455
9456         /* andxoffset */
9457         andxoffset = tvb_get_letohs(tvb, offset);
9458         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9459         offset += 2;
9460
9461         /* reserved byte */
9462         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9463         offset += 1;
9464
9465         /* file name len */
9466         fn_len = tvb_get_letohs(tvb, offset);
9467         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
9468         offset += 2;
9469
9470         /* Create flags */
9471         offset = dissect_nt_create_bits(tvb, tree, offset);
9472
9473         /* root directory fid */
9474         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
9475         offset += 4;
9476
9477         /* nt access mask */
9478         offset = dissect_smb_access_mask(tvb, tree, offset);
9479
9480         /* allocation size */
9481         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9482         offset += 8;
9483
9484         /* Extended File Attributes */
9485         offset = dissect_file_ext_attr(tvb, tree, offset);
9486
9487         /* share access */
9488         offset = dissect_nt_share_access(tvb, tree, offset);
9489
9490         /* create disposition */
9491         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
9492         offset += 4;
9493
9494         /* create options */
9495         offset = dissect_nt_create_options(tvb, tree, offset);
9496
9497         /* impersonation level */
9498         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
9499         offset += 4;
9500
9501         /* security flags */
9502         offset = dissect_nt_security_flags(tvb, tree, offset);
9503
9504         BYTE_COUNT;
9505
9506         /* file name */
9507         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9508         if (fn == NULL)
9509                 goto endofcommand;
9510         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9511                 fn);
9512         COUNT_BYTES(fn_len);
9513
9514         if (check_col(pinfo->cinfo, COL_INFO)) {
9515                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
9516         }
9517
9518         END_OF_SMB
9519
9520         /* call AndXCommand (if there are any) */
9521         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9522
9523         return offset;
9524 }
9525
9526
9527 static int
9528 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9529 {
9530         guint8  wc, cmd=0xff;
9531         guint16 andxoffset=0;
9532         guint16 bc;
9533         guint16 fid;
9534
9535         WORD_COUNT;
9536
9537         /* next smb command */
9538         cmd = tvb_get_guint8(tvb, offset);
9539         if(cmd!=0xff){
9540                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9541         } else {
9542                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9543         }
9544         offset += 1;
9545
9546         /* reserved byte */
9547         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9548         offset += 1;
9549
9550         /* andxoffset */
9551         andxoffset = tvb_get_letohs(tvb, offset);
9552         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9553         offset += 2;
9554
9555         /* oplock level */
9556         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
9557         offset += 1;
9558
9559         /* fid */
9560         fid = tvb_get_letohs(tvb, offset);
9561         add_fid(tvb, pinfo, tree, offset, 2, fid);
9562         offset += 2;
9563
9564         /* create action */
9565         /*XXX is this really the same as create disposition in the request? it looks so*/
9566         /* No, it is not. It is the same as the create action from an Open&X request ... RJS */
9567         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
9568         offset += 4;
9569
9570         /* create time */
9571         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
9572
9573         /* access time */
9574         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
9575
9576         /* last write time */
9577         offset = dissect_smb_64bit_time(tvb, tree, offset,
9578                 hf_smb_last_write_time);
9579
9580         /* last change time */
9581         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
9582
9583         /* Extended File Attributes */
9584         offset = dissect_file_ext_attr(tvb, tree, offset);
9585
9586         /* allocation size */
9587         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9588         offset += 8;
9589
9590         /* end of file */
9591         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9592         offset += 8;
9593
9594         /* File Type */
9595         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
9596         offset += 2;
9597
9598         /* IPC State */
9599         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9600
9601         /* is directory */
9602         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9603         offset += 1;
9604
9605         BYTE_COUNT;
9606
9607         END_OF_SMB
9608
9609         /* call AndXCommand (if there are any) */
9610         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9611
9612         return offset;
9613 }
9614
9615
9616 static int
9617 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9618 {
9619         guint8 wc;
9620         guint16 bc;
9621
9622         WORD_COUNT;
9623
9624         BYTE_COUNT;
9625
9626         END_OF_SMB
9627
9628         return offset;
9629 }
9630
9631 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9632    BEGIN Transaction/Transaction2 Primary and secondary requests
9633    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9634
9635
9636 const value_string trans2_cmd_vals[] = {
9637         { 0x00,         "OPEN2" },
9638         { 0x01,         "FIND_FIRST2" },
9639         { 0x02,         "FIND_NEXT2" },
9640         { 0x03,         "QUERY_FS_INFO" },
9641         { 0x04,         "SET_FS_QUOTA" },
9642         { 0x05,         "QUERY_PATH_INFO" },
9643         { 0x06,         "SET_PATH_INFO" },
9644         { 0x07,         "QUERY_FILE_INFO" },
9645         { 0x08,         "SET_FILE_INFO" },
9646         { 0x09,         "FSCTL" },
9647         { 0x0A,         "IOCTL2" },
9648         { 0x0B,         "FIND_NOTIFY_FIRST" },
9649         { 0x0C,         "FIND_NOTIFY_NEXT" },
9650         { 0x0D,         "CREATE_DIRECTORY" },
9651         { 0x0E,         "SESSION_SETUP" },
9652         { 0x10,         "GET_DFS_REFERRAL" },
9653         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
9654         { 0,    NULL }
9655 };
9656
9657 static const true_false_string tfs_tf_dtid = {
9658         "Also DISCONNECT TID",
9659         "Do NOT disconnect TID"
9660 };
9661 static const true_false_string tfs_tf_owt = {
9662         "One Way Transaction (NO RESPONSE)",
9663         "Two way transaction"
9664 };
9665
9666 static const true_false_string tfs_ff2_backup = {
9667         "Find WITH backup intent",
9668         "No backup intent"
9669 };
9670 static const true_false_string tfs_ff2_continue = {
9671         "CONTINUE search from previous position",
9672         "New search, do NOT continue from previous position"
9673 };
9674 static const true_false_string tfs_ff2_resume = {
9675         "Return RESUME keys",
9676         "Do NOT return resume keys"
9677 };
9678 static const true_false_string tfs_ff2_close_eos = {
9679         "CLOSE search if END OF SEARCH is reached",
9680         "Do NOT close search if end of search reached"
9681 };
9682 static const true_false_string tfs_ff2_close = {
9683         "CLOSE search after this request",
9684         "Do NOT close search after this request"
9685 };
9686
9687 /* used by
9688    TRANS2_FIND_FIRST2
9689 */
9690 static const value_string ff2_il_vals[] = {
9691         { 1,            "Info Standard"},
9692         { 2,            "Info Query EA Size"},
9693         { 3,            "Info Query EAs From List"},
9694         { 0x0101,       "Find File Directory Info"},
9695         { 0x0102,       "Find File Full Directory Info"},
9696         { 0x0103,       "Find File Names Info"},
9697         { 0x0104,       "Find File Both Directory Info"},
9698         { 0x0202,       "Find File UNIX"},
9699         {0, NULL}
9700 };
9701
9702 /* values used by :
9703         TRANS2_QUERY_PATH_INFORMATION
9704         TRANS2_QUERY_FILE_INFORMATION
9705 */
9706 static const value_string qpi_loi_vals[] = {
9707         { 1,            "Info Standard"},
9708         { 2,            "Info Query EA Size"},
9709         { 3,            "Info Query EAs From List"},
9710         { 4,            "Info Query All EAs"},
9711         { 6,            "Info Is Name Valid"},
9712         { 0x0101,       "Query File Basic Info"},
9713         { 0x0102,       "Query File Standard Info"},
9714         { 0x0103,       "Query File EA Info"},
9715         { 0x0104,       "Query File Name Info"},
9716         { 0x0107,       "Query File All Info"},
9717         { 0x0108,       "Query File Alt Name Info"},
9718         { 0x0109,       "Query File Stream Info"},
9719         { 0x010b,       "Query File Compression Info"},
9720         { 0x0200,       "Query File Unix Basic"},
9721         { 0x0201,       "Query File Unix Link"},
9722         { 1004,         "Query File Basic Info"},
9723         { 1005,         "Query File Standard Info"},
9724         { 1006,         "Query File Internal Info"},
9725         { 1007,         "Query File EA Info"},
9726         { 1009,         "Query File Name Info"},
9727         { 1010,         "Query File Rename Info"},
9728         { 1011,         "Query File Link Info"},
9729         { 1012,         "Query File Names Info"},
9730         { 1013,         "Query File Disposition Info"},
9731         { 1014,         "Query File Position Info"},
9732         { 1015,         "Query File Full EA Info"},
9733         { 1016,         "Query File Mode Info"},
9734         { 1017,         "Query File Alignment Info"},
9735         { 1018,         "Query File All Info"},
9736         { 1019,         "Query File Allocation Info"},
9737         { 1020,         "Query File End of File Info"},
9738         { 1021,         "Query File Alt Name Info"},
9739         { 1022,         "Query File Stream Info"},
9740         { 1023,         "Query File Pipe Info"},
9741         { 1024,         "Query File Pipe Local Info"},
9742         { 1025,         "Query File Pipe Remote Info"},
9743         { 1026,         "Query File Mailslot Query Info"},
9744         { 1027,         "Query File Mailslot Set Info"},
9745         { 1028,         "Query File Compression Info"},
9746         { 1029,         "Query File ObjectID Info"},
9747         { 1030,         "Query File Completion Info"},
9748         { 1031,         "Query File Move Cluster Info"},
9749         { 1032,         "Query File Quota Info"},
9750         { 1033,         "Query File Reparsepoint Info"},
9751         { 1034,         "Query File Network Open Info"},
9752         { 1035,         "Query File Attribute Tag Info"},
9753         { 1036,         "Query File Tracking Info"},
9754         { 1037,         "Query File Maximum Info"},
9755         {0, NULL}
9756 };
9757
9758 /* values used by :
9759         TRANS2_SET_PATH_INFORMATION
9760         TRANS2_SET_FILE_INFORMATION
9761         (the SNIA CIFS spec lists some only for TRANS2_SET_FILE_INFORMATION,
9762         but I'm assuming they apply to TRANS2_SET_PATH_INFORMATION as
9763         well; note that they're different from the QUERY_PATH_INFORMATION
9764         and QUERY_FILE_INFORMATION values!)
9765 */
9766 static const value_string spi_loi_vals[] = {
9767         { 1,            "Info Standard"},
9768         { 2,            "Info Query EA Size"},
9769         { 4,            "Info Query All EAs"},
9770         { 0x0101,       "Set File Basic Info"},
9771         { 0x0102,       "Set File Disposition Info"},
9772         { 0x0103,       "Set File Allocation Info"},
9773         { 0x0104,       "Set File End Of File Info"},
9774         { 0x0200,       "Set File Unix Basic"},
9775         { 0x0201,       "Set File Unix Link"},
9776         { 0x0202,       "Set File Unix HardLink"},
9777         { 1004,         "Set File Basic Info"},
9778         { 1010,         "Set Rename Information"},
9779         { 1013,         "Set Disposition Information"},
9780         { 1014,         "Set Position Information"},
9781         { 1016,         "Set Mode Information"},
9782         { 1019,         "Set Allocation Information"},
9783         { 1020,         "Set EOF Information"},
9784         { 1023,         "Set File Pipe Information"},
9785         { 1025,         "Set File Pipe Remote Information"},
9786         { 1029,         "Set Copy On Write Information"},
9787         { 1032,         "Set OLE Class ID Information"},
9788         { 1039,         "Set Inherit Context Index Information"},
9789         { 1040,         "Set OLE Information (?)"},
9790         {0, NULL}
9791 };
9792
9793 static const value_string qfsi_vals[] = {
9794         { 1,            "Info Allocation"},
9795         { 2,            "Info Volume"},
9796         { 0x0101,       "Query FS Label Info"},
9797         { 0x0102,       "Query FS Volume Info"},
9798         { 0x0103,       "Query FS Size Info"},
9799         { 0x0104,       "Query FS Device Info"},
9800         { 0x0105,       "Query FS Attribute Info"},
9801         { 0x0200,       "Unix Query FS Info"},
9802         { 0x0301,       "Mac Query FS Info"},
9803         { 1001,         "Query FS Label Info"},
9804         { 1002,         "Query FS Volume Info"},
9805         { 1003,         "Query FS Size Info"},
9806         { 1004,         "Query FS Device Info"},
9807         { 1005,         "Query FS Attribute Info"},
9808         { 1006,         "Query FS Quota Info"},
9809         { 1007,         "Query Full FS Size Info"},
9810         { 1008,         "Object ID Information"},
9811         {0, NULL}
9812 };
9813
9814 static const value_string nt_rename_vals[] = {
9815         { 0x0103,       "Create Hard Link"},
9816         {0, NULL}
9817 };
9818
9819
9820 static const value_string delete_pending_vals[] = {
9821         {0,     "Normal, no pending delete"},
9822         {1,     "This object has DELETE PENDING"},
9823         {0, NULL}
9824 };
9825
9826 static const value_string alignment_vals[] = {
9827         {0,     "Byte alignment"},
9828         {1,     "Word (16bit) alignment"},
9829         {3,     "Long (32bit) alignment"},
9830         {7,     "8 byte boundary alignment"},
9831         {0x0f,  "16 byte boundary alignment"},
9832         {0x1f,  "32 byte boundary alignment"},
9833         {0x3f,  "64 byte boundary alignment"},
9834         {0x7f,  "128 byte boundary alignment"},
9835         {0xff,  "256 byte boundary alignment"},
9836         {0x1ff, "512 byte boundary alignment"},
9837         {0, NULL}
9838 };
9839
9840 static const true_false_string tfs_marked_for_deletion = {
9841         "File is MARKED FOR DELETION",
9842         "File is NOT marked for deletion"
9843 };
9844
9845 static const true_false_string tfs_get_dfs_server_hold_storage = {
9846         "Referral SERVER HOLDS STORAGE for the file",
9847         "Referral server does NOT hold storage for the file"
9848 };
9849 static const true_false_string tfs_get_dfs_fielding = {
9850         "The server in referral is FIELDING CAPABLE",
9851         "The server in referrals is NOT fielding capable"
9852 };
9853
9854 static const true_false_string tfs_dfs_referral_flags_strip = {
9855         "STRIP off pathconsumed characters before submitting",
9856         "Do NOT strip off any characters"
9857 };
9858
9859 static const value_string dfs_referral_server_type_vals[] = {
9860         {0,     "Don't know"},
9861         {1,     "SMB Server"},
9862         {2,     "Netware Server"},
9863         {3,     "Domain Server"},
9864         {0, NULL}
9865 };
9866
9867
9868 static const true_false_string tfs_device_char_removable = {
9869         "This is a REMOVABLE device",
9870         "This is NOT a removable device"
9871 };
9872 static const true_false_string tfs_device_char_read_only = {
9873         "This is a READ-ONLY device",
9874         "This is NOT a read-only device"
9875 };
9876 static const true_false_string tfs_device_char_floppy = {
9877         "This is a FLOPPY DISK device",
9878         "This is NOT a floppy disk device"
9879 };
9880 static const true_false_string tfs_device_char_write_once = {
9881         "This is a WRITE-ONCE device",
9882         "This is NOT a write-once device"
9883 };
9884 static const true_false_string tfs_device_char_remote = {
9885         "This is a REMOTE device",
9886         "This is NOT a remote device"
9887 };
9888 static const true_false_string tfs_device_char_mounted = {
9889         "This device is MOUNTED",
9890         "This device is NOT mounted"
9891 };
9892 static const true_false_string tfs_device_char_virtual = {
9893         "This is a VIRTUAL device",
9894         "This is NOT a virtual device"
9895 };
9896
9897
9898 static const true_false_string tfs_fs_attr_css = {
9899         "This FS supports CASE SENSITIVE SEARCHes",
9900         "This FS does NOT support case sensitive searches"
9901 };
9902 static const true_false_string tfs_fs_attr_cpn = {
9903         "This FS supports CASE PRESERVED NAMES",
9904         "This FS does NOT support case preserved names"
9905 };
9906 static const true_false_string tfs_fs_attr_pacls = {
9907         "This FS supports PERSISTENT ACLs",
9908         "This FS does NOT support persistent acls"
9909 };
9910 static const true_false_string tfs_fs_attr_fc = {
9911         "This FS supports COMPRESSED FILES",
9912         "This FS does NOT support compressed files"
9913 };
9914 static const true_false_string tfs_fs_attr_vq = {
9915         "This FS supports VOLUME QUOTAS",
9916         "This FS does NOT support volume quotas"
9917 };
9918 static const true_false_string tfs_fs_attr_dim = {
9919         "This FS is on a MOUNTED DEVICE",
9920         "This FS is NOT on a mounted device"
9921 };
9922 static const true_false_string tfs_fs_attr_vic = {
9923         "This FS is on a COMPRESSED VOLUME",
9924         "This FS is NOT on a compressed volume"
9925 };
9926
9927 #define FF2_RESUME      0x0004
9928
9929 static int
9930 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9931 {
9932         guint16 mask;
9933         proto_item *item = NULL;
9934         proto_tree *tree = NULL;
9935         smb_info_t *si;
9936         smb_transact2_info_t *t2i;
9937
9938         mask = tvb_get_letohs(tvb, offset);
9939
9940         si = (smb_info_t *)pinfo->private_data;
9941         if (si->sip != NULL) {
9942                 t2i = si->sip->extra_info;
9943                 if (t2i != NULL) {
9944                         if (!pinfo->fd->flags.visited)
9945                                 t2i->resume_keys = (mask & FF2_RESUME);
9946                 }
9947         }
9948
9949         if(parent_tree){
9950                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9951                         "Flags: 0x%04x", mask);
9952                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
9953         }
9954
9955         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
9956                 tvb, offset, 2, mask);
9957         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
9958                 tvb, offset, 2, mask);
9959         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
9960                 tvb, offset, 2, mask);
9961         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
9962                 tvb, offset, 2, mask);
9963         proto_tree_add_boolean(tree, hf_smb_ff2_close,
9964                 tvb, offset, 2, mask);
9965
9966         offset += 2;
9967
9968         return offset;
9969 }
9970
9971 #if 0
9972 static int
9973 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9974 {
9975         guint16 mask;
9976         proto_item *item = NULL;
9977         proto_tree *tree = NULL;
9978
9979         mask = tvb_get_letohs(tvb, offset);
9980
9981         if(parent_tree){
9982                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9983                         "IO Flag: 0x%04x", mask);
9984                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
9985         }
9986
9987         proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
9988                 tvb, offset, 2, mask);
9989         proto_tree_add_boolean(tree, hf_smb_sfi_caching,
9990                 tvb, offset, 2, mask);
9991
9992         offset += 2;
9993
9994         return offset;
9995 }
9996 #endif
9997
9998 static int
9999 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
10000     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
10001 {
10002         proto_item *item = NULL;
10003         proto_tree *tree = NULL;
10004         smb_info_t *si;
10005         smb_transact2_info_t *t2i;
10006         int fn_len;
10007         const char *fn;
10008
10009         si = (smb_info_t *)pinfo->private_data;
10010         if (si->sip != NULL)
10011                 t2i = si->sip->extra_info;
10012         else
10013                 t2i = NULL;
10014
10015         if(parent_tree){
10016                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
10017                                 "%s Parameters",
10018                                 val_to_str(subcmd, trans2_cmd_vals,
10019                                            "Unknown (0x%02x)"));
10020                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
10021         }
10022
10023         switch(subcmd){
10024         case 0x00:      /*TRANS2_OPEN2*/
10025                 /* open flags */
10026                 CHECK_BYTE_COUNT_TRANS(2);
10027                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
10028                 bc -= 2;
10029
10030                 /* desired access */
10031                 CHECK_BYTE_COUNT_TRANS(2);
10032                 offset = dissect_access(tvb, tree, offset, "Desired");
10033                 bc -= 2;
10034
10035                 /* Search Attributes */
10036                 CHECK_BYTE_COUNT_TRANS(2);
10037                 offset = dissect_search_attributes(tvb, tree, offset);
10038                 bc -= 2;
10039
10040                 /* File Attributes */
10041                 CHECK_BYTE_COUNT_TRANS(2);
10042                 offset = dissect_file_attributes(tvb, tree, offset, 2);
10043                 bc -= 2;
10044
10045                 /* create time */
10046                 CHECK_BYTE_COUNT_TRANS(4);
10047                 offset = dissect_smb_datetime(tvb, tree, offset,
10048                         hf_smb_create_time,
10049                         hf_smb_create_dos_date, hf_smb_create_dos_time,
10050                         TRUE);
10051                 bc -= 4;
10052
10053                 /* open function */
10054                 CHECK_BYTE_COUNT_TRANS(2);
10055                 offset = dissect_open_function(tvb, tree, offset);
10056                 bc -= 2;
10057
10058                 /* allocation size */
10059                 CHECK_BYTE_COUNT_TRANS(4);
10060                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10061                 COUNT_BYTES_TRANS(4);
10062
10063                 /* 10 reserved bytes */
10064                 CHECK_BYTE_COUNT_TRANS(10);
10065                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
10066                 COUNT_BYTES_TRANS(10);
10067
10068                 /* file name */
10069                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10070                 CHECK_STRING_TRANS(fn);
10071                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10072                         fn);
10073                 COUNT_BYTES_TRANS(fn_len);
10074
10075                 if (check_col(pinfo->cinfo, COL_INFO)) {
10076                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10077                         fn);
10078                 }
10079                 break;
10080         case 0x01:      /*TRANS2_FIND_FIRST2*/
10081                 /* Search Attributes */
10082                 CHECK_BYTE_COUNT_TRANS(2);
10083                 offset = dissect_search_attributes(tvb, tree, offset);
10084                 bc -= 2;
10085
10086                 /* search count */
10087                 CHECK_BYTE_COUNT_TRANS(2);
10088                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10089                 COUNT_BYTES_TRANS(2);
10090
10091                 /* Find First2 flags */
10092                 CHECK_BYTE_COUNT_TRANS(2);
10093                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10094                 bc -= 2;
10095
10096                 /* Find First2 information level */
10097                 CHECK_BYTE_COUNT_TRANS(2);
10098                 si->info_level = tvb_get_letohs(tvb, offset);
10099                 if (!pinfo->fd->flags.visited)
10100                         t2i->info_level = si->info_level;
10101                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10102                 COUNT_BYTES_TRANS(2);
10103
10104                 /* storage type */
10105                 CHECK_BYTE_COUNT_TRANS(4);
10106                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
10107                 COUNT_BYTES_TRANS(4);
10108
10109                 /* search pattern */
10110                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10111                 CHECK_STRING_TRANS(fn);
10112                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
10113                         fn);
10114                 COUNT_BYTES_TRANS(fn_len);
10115
10116                 if (check_col(pinfo->cinfo, COL_INFO)) {
10117                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
10118                         fn);
10119                 }
10120
10121                 break;
10122         case 0x02:      /*TRANS2_FIND_NEXT2*/
10123                 /* sid */
10124                 CHECK_BYTE_COUNT_TRANS(2);
10125                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
10126                 COUNT_BYTES_TRANS(2);
10127
10128                 /* search count */
10129                 CHECK_BYTE_COUNT_TRANS(2);
10130                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10131                 COUNT_BYTES_TRANS(2);
10132
10133                 /* Find First2 information level */
10134                 CHECK_BYTE_COUNT_TRANS(2);
10135                 si->info_level = tvb_get_letohs(tvb, offset);
10136                 if (!pinfo->fd->flags.visited)
10137                         t2i->info_level = si->info_level;
10138                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10139                 COUNT_BYTES_TRANS(2);
10140
10141                 /* resume key */
10142                 CHECK_BYTE_COUNT_TRANS(4);
10143                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
10144                 COUNT_BYTES_TRANS(4);
10145
10146                 /* Find First2 flags */
10147                 CHECK_BYTE_COUNT_TRANS(2);
10148                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10149                 bc -= 2;
10150
10151                 /* file name */
10152                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10153                 CHECK_STRING_TRANS(fn);
10154                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10155                         fn);
10156                 COUNT_BYTES_TRANS(fn_len);
10157
10158                 if (check_col(pinfo->cinfo, COL_INFO)) {
10159                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
10160                         fn);
10161                 }
10162
10163                 break;
10164         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10165                 /* level of interest */
10166                 CHECK_BYTE_COUNT_TRANS(2);
10167                 si->info_level = tvb_get_letohs(tvb, offset);
10168                 if (!pinfo->fd->flags.visited)
10169                         t2i->info_level = si->info_level;
10170                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
10171                 COUNT_BYTES_TRANS(2);
10172
10173                 if (check_col(pinfo->cinfo, COL_INFO))
10174                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
10175                                         val_to_str(si->info_level, qfsi_vals, 
10176                                                    "Unknown (0x%02x)"));
10177
10178                 break;
10179         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10180                 /* level of interest */
10181                 CHECK_BYTE_COUNT_TRANS(2);
10182                 si->info_level = tvb_get_letohs(tvb, offset);
10183                 if (!pinfo->fd->flags.visited)
10184                         t2i->info_level = si->info_level;
10185                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10186                 COUNT_BYTES_TRANS(2);
10187
10188                 if (check_col(pinfo->cinfo, COL_INFO)) {
10189                         col_append_fstr(
10190                                 pinfo->cinfo, COL_INFO, ", %s", 
10191                                 val_to_str(si->info_level, qpi_loi_vals, 
10192                                            "Unknown (%u)"));
10193                 }
10194
10195                 /* 4 reserved bytes */
10196                 CHECK_BYTE_COUNT_TRANS(4);
10197                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10198                 COUNT_BYTES_TRANS(4);
10199
10200                 /* file name */
10201                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10202                 CHECK_STRING_TRANS(fn);
10203                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10204                         fn);
10205                 COUNT_BYTES_TRANS(fn_len);
10206
10207                 if (check_col(pinfo->cinfo, COL_INFO)) {
10208                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10209                         fn);
10210                 }
10211
10212                 break;
10213         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10214                 /* level of interest */
10215                 CHECK_BYTE_COUNT_TRANS(2);
10216                 si->info_level = tvb_get_letohs(tvb, offset);
10217                 if (!pinfo->fd->flags.visited)
10218                         t2i->info_level = si->info_level;
10219                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10220                 COUNT_BYTES_TRANS(2);
10221
10222                 /* 4 reserved bytes */
10223                 CHECK_BYTE_COUNT_TRANS(4);
10224                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10225                 COUNT_BYTES_TRANS(4);
10226
10227                 /* file name */
10228                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10229                 CHECK_STRING_TRANS(fn);
10230                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10231                         fn);
10232                 COUNT_BYTES_TRANS(fn_len);
10233
10234                 if (check_col(pinfo->cinfo, COL_INFO)) {
10235                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10236                         fn);
10237                 }
10238
10239                 break;
10240         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
10241                 guint16 fid;
10242
10243                 /* fid */
10244                 CHECK_BYTE_COUNT_TRANS(2);
10245                 fid = tvb_get_letohs(tvb, offset);
10246                 add_fid(tvb, pinfo, tree, offset, 2, fid);
10247                 COUNT_BYTES_TRANS(2);
10248
10249                 /* level of interest */
10250                 CHECK_BYTE_COUNT_TRANS(2);
10251                 si->info_level = tvb_get_letohs(tvb, offset);
10252                 if (!pinfo->fd->flags.visited)
10253                         t2i->info_level = si->info_level;
10254                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10255                 COUNT_BYTES_TRANS(2);
10256
10257                 if (check_col(pinfo->cinfo, COL_INFO)) {
10258                         col_append_fstr(
10259                                 pinfo->cinfo, COL_INFO, ", %s", 
10260                                 val_to_str(si->info_level, qpi_loi_vals, 
10261                                            "Unknown (%u)"));
10262                 }
10263
10264                 break;
10265         }
10266         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
10267                 guint16 fid;
10268
10269                 /* fid */
10270                 CHECK_BYTE_COUNT_TRANS(2);
10271                 fid = tvb_get_letohs(tvb, offset);
10272                 add_fid(tvb, pinfo, tree, offset, 2, fid);
10273                 COUNT_BYTES_TRANS(2);
10274
10275                 /* level of interest */
10276                 CHECK_BYTE_COUNT_TRANS(2);
10277                 si->info_level = tvb_get_letohs(tvb, offset);
10278                 if (!pinfo->fd->flags.visited)
10279                         t2i->info_level = si->info_level;
10280                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10281                 COUNT_BYTES_TRANS(2);
10282
10283 #if 0
10284                 /*
10285                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10286                  * Extensions Version 3.0, Document Version 1.11,
10287                  * July 19, 1990" says this is I/O flags, but it's
10288                  * reserved in the SNIA spec, and some clients appear
10289                  * to leave junk in it.
10290                  *
10291                  * Is this some field used only if a particular
10292                  * dialect was negotiated, so that clients can feel
10293                  * safe not setting it if they haven't negotiated that
10294                  * dialect?  Or do the (non-OS/2) clients simply not care
10295                  * about that particular OS/2-oriented dialect?
10296                  */
10297
10298                 /* IO Flag */
10299                 CHECK_BYTE_COUNT_TRANS(2);
10300                 offset = dissect_sfi_ioflag(tvb, tree, offset);
10301                 bc -= 2;
10302 #else
10303                 /* 2 reserved bytes */
10304                 CHECK_BYTE_COUNT_TRANS(2);
10305                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10306                 COUNT_BYTES_TRANS(2);
10307 #endif
10308
10309                 break;
10310         }
10311         case 0x09:      /*TRANS2_FSCTL*/
10312                 /* this call has no parameter block in the request */
10313
10314                 /*
10315                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10316                  * Extensions Version 3.0, Document Version 1.11,
10317                  * July 19, 1990" says this this contains a
10318                  * "File system specific parameter block".  (That means
10319                  * we may not be able to dissect it in any case.)
10320                  */
10321                 break;
10322         case 0x0a:      /*TRANS2_IOCTL2*/
10323                 /* this call has no parameter block in the request */
10324
10325                 /*
10326                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10327                  * Extensions Version 3.0, Document Version 1.11,
10328                  * July 19, 1990" says this this contains a
10329                  * "Device/function specific parameter block".  (That
10330                  * means we may not be able to dissect it in any case.)
10331                  */
10332                 break;
10333         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
10334                 /* Search Attributes */
10335                 CHECK_BYTE_COUNT_TRANS(2);
10336                 offset = dissect_search_attributes(tvb, tree, offset);
10337                 bc -= 2;
10338
10339                 /* Number of changes to wait for */
10340                 CHECK_BYTE_COUNT_TRANS(2);
10341                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10342                 COUNT_BYTES_TRANS(2);
10343
10344                 /* Find Notify information level */
10345                 CHECK_BYTE_COUNT_TRANS(2);
10346                 si->info_level = tvb_get_letohs(tvb, offset);
10347                 if (!pinfo->fd->flags.visited)
10348                         t2i->info_level = si->info_level;
10349                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
10350                 COUNT_BYTES_TRANS(2);
10351
10352                 /* 4 reserved bytes */
10353                 CHECK_BYTE_COUNT_TRANS(4);
10354                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10355                 COUNT_BYTES_TRANS(4);
10356
10357                 /* file name */
10358                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10359                 CHECK_STRING_TRANS(fn);
10360                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10361                         fn);
10362                 COUNT_BYTES_TRANS(fn_len);
10363
10364                 if (check_col(pinfo->cinfo, COL_INFO)) {
10365                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10366                         fn);
10367                 }
10368
10369                 break;
10370         }
10371         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
10372                 /* Monitor handle */
10373                 CHECK_BYTE_COUNT_TRANS(2);
10374                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
10375                 COUNT_BYTES_TRANS(2);
10376
10377                 /* Number of changes to wait for */
10378                 CHECK_BYTE_COUNT_TRANS(2);
10379                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10380                 COUNT_BYTES_TRANS(2);
10381
10382                 break;
10383         }
10384         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10385                 /* 4 reserved bytes */
10386                 CHECK_BYTE_COUNT_TRANS(4);
10387                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10388                 COUNT_BYTES_TRANS(4);
10389
10390                 /* dir name */
10391                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
10392                         FALSE, FALSE, &bc);
10393                 CHECK_STRING_TRANS(fn);
10394                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
10395                         fn);
10396                 COUNT_BYTES_TRANS(fn_len);
10397
10398                 if (check_col(pinfo->cinfo, COL_INFO)) {
10399                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
10400                         fn);
10401                 }
10402                 break;
10403         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10404                 /* XXX unknown structure*/
10405                 break;
10406         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10407                 /* referral level */
10408                 CHECK_BYTE_COUNT_TRANS(2);
10409                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
10410                 COUNT_BYTES_TRANS(2);
10411
10412                 /* file name */
10413                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10414                 CHECK_STRING_TRANS(fn);
10415                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10416                         fn);
10417                 COUNT_BYTES_TRANS(fn_len);
10418
10419                 if (check_col(pinfo->cinfo, COL_INFO)) {
10420                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10421                         fn);
10422                 }
10423
10424                 break;
10425         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10426                 /* file name */
10427                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10428                 CHECK_STRING_TRANS(fn);
10429                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10430                         fn);
10431                 COUNT_BYTES_TRANS(fn_len);
10432
10433                 if (check_col(pinfo->cinfo, COL_INFO)) {
10434                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10435                         fn);
10436                 }
10437
10438                 break;
10439         }
10440
10441         /* ooops there were data we didnt know how to process */
10442         if(bc != 0){
10443                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, bc, TRUE);
10444                 offset += bc;
10445         }
10446
10447         return offset;
10448 }
10449
10450 /*
10451  * XXX - just use "dissect_connect_flags()" here?
10452  */
10453 static guint16
10454 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10455 {
10456         guint16 mask;
10457         proto_item *item = NULL;
10458         proto_tree *tree = NULL;
10459
10460         mask = tvb_get_letohs(tvb, offset);
10461
10462         if(parent_tree){
10463                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10464                         "Flags: 0x%04x", mask);
10465                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
10466         }
10467
10468         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
10469                 tvb, offset, 2, mask);
10470         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
10471                 tvb, offset, 2, mask);
10472
10473         return mask;
10474 }
10475
10476
10477 static int
10478 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10479 {
10480         guint16 mask;
10481         proto_item *item = NULL;
10482         proto_tree *tree = NULL;
10483
10484         mask = tvb_get_letohs(tvb, offset);
10485
10486         if(parent_tree){
10487                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10488                         "Flags: 0x%04x", mask);
10489                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
10490         }
10491
10492         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
10493                 tvb, offset, 2, mask);
10494         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
10495                 tvb, offset, 2, mask);
10496
10497         offset += 2;
10498         return offset;
10499 }
10500
10501 static int
10502 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10503 {
10504         guint16 mask;
10505         proto_item *item = NULL;
10506         proto_tree *tree = NULL;
10507
10508         mask = tvb_get_letohs(tvb, offset);
10509
10510         if(parent_tree){
10511                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10512                         "Flags: 0x%04x", mask);
10513                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
10514         }
10515
10516         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
10517                 tvb, offset, 2, mask);
10518
10519         offset += 2;
10520
10521         return offset;
10522 }
10523
10524
10525 /* dfs inconsistency data  (4.4.2)
10526 */
10527 static int
10528 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
10529     proto_tree *tree, int offset, guint16 *bcp)
10530 {
10531         smb_info_t *si = pinfo->private_data;
10532         int fn_len;
10533         const char *fn;
10534
10535         /*XXX shouldn this data hold version and size? unclear from doc*/
10536         /* referral version */
10537         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10538         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
10539         COUNT_BYTES_TRANS_SUBR(2);
10540
10541         /* referral size */
10542         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10543         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
10544         COUNT_BYTES_TRANS_SUBR(2);
10545
10546         /* referral server type */
10547         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10548         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10549         COUNT_BYTES_TRANS_SUBR(2);
10550
10551         /* referral flags */
10552         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10553         offset = dissect_dfs_referral_flags(tvb, tree, offset);
10554         *bcp -= 2;
10555
10556         /* node name */
10557         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10558         CHECK_STRING_TRANS_SUBR(fn);
10559         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10560                 fn);
10561         COUNT_BYTES_TRANS_SUBR(fn_len);
10562
10563         return offset;
10564 }
10565
10566 /* get dfs referral data  (4.4.1)
10567 */
10568 static int
10569 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
10570     proto_tree *tree, int offset, guint16 *bcp)
10571 {
10572         smb_info_t *si = pinfo->private_data;
10573         guint16 numref;
10574         guint16 refsize;
10575         guint16 pathoffset;
10576         guint16 altpathoffset;
10577         guint16 nodeoffset;
10578         int fn_len;
10579         int stroffset;
10580         int offsetoffset;
10581         guint16 save_bc;
10582         const char *fn;
10583         int unklen;
10584         int ucstring_end;
10585         int ucstring_len;
10586
10587         /* path consumed */
10588         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10589         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
10590         COUNT_BYTES_TRANS_SUBR(2);
10591
10592         /* num referrals */
10593         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10594         numref = tvb_get_letohs(tvb, offset);
10595         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
10596         COUNT_BYTES_TRANS_SUBR(2);
10597
10598         /* get dfs flags */
10599         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10600         offset = dissect_get_dfs_flags(tvb, tree, offset);
10601         *bcp -= 2;
10602
10603         /* XXX - in at least one capture there appears to be 2 bytes
10604            of stuff after the Dfs flags, perhaps so that the header
10605            in front of the referral list is a multiple of 4 bytes long. */
10606         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10607         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
10608         COUNT_BYTES_TRANS_SUBR(2);
10609
10610         /* if there are any referrals */
10611         if(numref){
10612                 proto_item *ref_item = NULL;
10613                 proto_tree *ref_tree = NULL;
10614                 int old_offset=offset;
10615
10616                 if(tree){
10617                         ref_item = proto_tree_add_text(tree,
10618                                 tvb, offset, *bcp, "Referrals");
10619                         ref_tree = proto_item_add_subtree(ref_item,
10620                                 ett_smb_dfs_referrals);
10621                 }
10622                 ucstring_end = -1;
10623
10624                 while(numref--){
10625                         proto_item *ri = NULL;
10626                         proto_tree *rt = NULL;
10627                         int old_offset=offset;
10628                         guint16 version;
10629
10630                         if(tree){
10631                                 ri = proto_tree_add_text(ref_tree,
10632                                         tvb, offset, *bcp, "Referral");
10633                                 rt = proto_item_add_subtree(ri,
10634                                         ett_smb_dfs_referral);
10635                         }
10636
10637                         /* referral version */
10638                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10639                         version = tvb_get_letohs(tvb, offset);
10640                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
10641                                 tvb, offset, 2, version);
10642                         COUNT_BYTES_TRANS_SUBR(2);
10643
10644                         /* referral size */
10645                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10646                         refsize = tvb_get_letohs(tvb, offset);
10647                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
10648                         COUNT_BYTES_TRANS_SUBR(2);
10649
10650                         /* referral server type */
10651                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10652                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10653                         COUNT_BYTES_TRANS_SUBR(2);
10654
10655                         /* referral flags */
10656                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10657                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
10658                         *bcp -= 2;
10659
10660                         switch(version){
10661
10662                         case 1:
10663                                 /* node name */
10664                                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10665                                 CHECK_STRING_TRANS_SUBR(fn);
10666                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10667                                         fn);
10668                                 COUNT_BYTES_TRANS_SUBR(fn_len);
10669                                 break;
10670
10671                         case 2:
10672                         case 3: /* XXX - like version 2, but not identical;
10673                                    seen in a capture, but the format isn't
10674                                    documented */
10675                                 /* proximity */
10676                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10677                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
10678                                 COUNT_BYTES_TRANS_SUBR(2);
10679
10680                                 /* ttl */
10681                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10682                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
10683                                 COUNT_BYTES_TRANS_SUBR(2);
10684
10685                                 /* path offset */
10686                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10687                                 pathoffset = tvb_get_letohs(tvb, offset);
10688                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
10689                                 COUNT_BYTES_TRANS_SUBR(2);
10690
10691                                 /* alt path offset */
10692                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10693                                 altpathoffset = tvb_get_letohs(tvb, offset);
10694                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
10695                                 COUNT_BYTES_TRANS_SUBR(2);
10696
10697                                 /* node offset */
10698                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10699                                 nodeoffset = tvb_get_letohs(tvb, offset);
10700                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
10701                                 COUNT_BYTES_TRANS_SUBR(2);
10702
10703                                 /* path */
10704                                 if (pathoffset != 0) {
10705                                         stroffset = old_offset + pathoffset;
10706                                         offsetoffset = stroffset - offset;
10707                                         if (offsetoffset > 0 &&
10708                                             *bcp > offsetoffset) {
10709                                                 save_bc = *bcp;
10710                                                 *bcp -= offsetoffset;
10711                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10712                                                 CHECK_STRING_TRANS_SUBR(fn);
10713                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
10714                                                         fn);
10715                                                 stroffset += fn_len;
10716                                                 if (ucstring_end < stroffset)
10717                                                         ucstring_end = stroffset;
10718                                                 *bcp = save_bc;
10719                                         }
10720                                 }
10721
10722                                 /* alt path */
10723                                 if (altpathoffset != 0) {
10724                                         stroffset = old_offset + altpathoffset;
10725                                         offsetoffset = stroffset - offset;
10726                                         if (offsetoffset > 0 &&
10727                                             *bcp > offsetoffset) {
10728                                                 save_bc = *bcp;
10729                                                 *bcp -= offsetoffset;
10730                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10731                                                 CHECK_STRING_TRANS_SUBR(fn);
10732                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
10733                                                         fn);
10734                                                 stroffset += fn_len;
10735                                                 if (ucstring_end < stroffset)
10736                                                         ucstring_end = stroffset;
10737                                                 *bcp = save_bc;
10738                                         }
10739                                 }
10740
10741                                 /* node */
10742                                 if (nodeoffset != 0) {
10743                                         stroffset = old_offset + nodeoffset;
10744                                         offsetoffset = stroffset - offset;
10745                                         if (offsetoffset > 0 &&
10746                                             *bcp > offsetoffset) {
10747                                                 save_bc = *bcp;
10748                                                 *bcp -= offsetoffset;
10749                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10750                                                 CHECK_STRING_TRANS_SUBR(fn);
10751                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
10752                                                         fn);
10753                                                 stroffset += fn_len;
10754                                                 if (ucstring_end < stroffset)
10755                                                         ucstring_end = stroffset;
10756                                                 *bcp = save_bc;
10757                                         }
10758                                 }
10759                                 break;
10760                         }
10761
10762                         /*
10763                          * Show anything beyond the length of the referral
10764                          * as unknown data.
10765                          */
10766                         unklen = (old_offset + refsize) - offset;
10767                         if (unklen < 0) {
10768                                 /*
10769                                  * XXX - the length is bogus.
10770                                  */
10771                                 unklen = 0;
10772                         }
10773                         if (unklen != 0) {
10774                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
10775                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
10776                                     offset, unklen, TRUE);
10777                                 COUNT_BYTES_TRANS_SUBR(unklen);
10778                         }
10779
10780                         proto_item_set_len(ri, offset-old_offset);
10781                 }
10782
10783                 /*
10784                  * Treat the offset past the end of the last Unicode
10785                  * string after the referrals (if any) as the last
10786                  * offset.
10787                  */
10788                 if (ucstring_end > offset) {
10789                         ucstring_len = ucstring_end - offset;
10790                         if (*bcp < ucstring_len)
10791                                 ucstring_len = *bcp;
10792                         offset += ucstring_len;
10793                         *bcp -= ucstring_len;
10794                 }
10795                 proto_item_set_len(ref_item, offset-old_offset);
10796         }
10797
10798         return offset;
10799 }
10800
10801
10802 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
10803    as described in 4.2.16.1
10804 */
10805 static int
10806 dissect_4_2_16_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10807     int offset, guint16 *bcp, gboolean *trunc)
10808 {
10809         /* create time */
10810         CHECK_BYTE_COUNT_SUBR(4);
10811         offset = dissect_smb_datetime(tvb, tree, offset,
10812                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
10813                 FALSE);
10814         *bcp -= 4;
10815
10816         /* access time */
10817         CHECK_BYTE_COUNT_SUBR(4);
10818         offset = dissect_smb_datetime(tvb, tree, offset,
10819                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
10820                 FALSE);
10821         *bcp -= 4;
10822
10823         /* last write time */
10824         CHECK_BYTE_COUNT_SUBR(4);
10825         offset = dissect_smb_datetime(tvb, tree, offset,
10826                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
10827                 FALSE);
10828         *bcp -= 4;
10829
10830         /* data size */
10831         CHECK_BYTE_COUNT_SUBR(4);
10832         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10833         COUNT_BYTES_SUBR(4);
10834
10835         /* allocation size */
10836         CHECK_BYTE_COUNT_SUBR(4);
10837         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10838         COUNT_BYTES_SUBR(4);
10839
10840         /* File Attributes */
10841         CHECK_BYTE_COUNT_SUBR(2);
10842         offset = dissect_file_attributes(tvb, tree, offset, 2);
10843         *bcp -= 2;
10844
10845         /* ea length */
10846         CHECK_BYTE_COUNT_SUBR(4);
10847         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10848         COUNT_BYTES_SUBR(4);
10849
10850         *trunc = FALSE;
10851         return offset;
10852 }
10853
10854 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
10855    as described in 4.2.16.2
10856 */
10857 static int
10858 dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10859     int offset, guint16 *bcp, gboolean *trunc)
10860 {
10861         guint8 name_len;
10862         guint16 data_len;
10863         /* EA size */
10864
10865         CHECK_BYTE_COUNT_SUBR(4);
10866         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10867         COUNT_BYTES_SUBR(4);
10868
10869         while (*bcp > 0) {
10870                 proto_item *item;
10871                 proto_tree *subtree;
10872                 int start_offset = offset;
10873                 guint8 *name;
10874
10875                 item = proto_tree_add_text(
10876                         tree, tvb, offset, 0, "Extended Attribute");
10877                 subtree = proto_item_add_subtree(item, ett_smb_ea);
10878
10879                 /* EA flags */
10880                 
10881                 CHECK_BYTE_COUNT_SUBR(1);
10882                 proto_tree_add_item(
10883                         subtree, hf_smb_ea_flags, tvb, offset, 1, TRUE);
10884                 COUNT_BYTES_SUBR(1);
10885
10886                 /* EA name length */
10887                 
10888                 name_len = tvb_get_guint8(tvb, offset);
10889
10890                 CHECK_BYTE_COUNT_SUBR(1);
10891                 proto_tree_add_item(
10892                         subtree, hf_smb_ea_name_length, tvb, offset, 1, TRUE);
10893                 COUNT_BYTES_SUBR(1);
10894
10895                 /* EA data length */
10896
10897                 data_len = tvb_get_letohs(tvb, offset);
10898                 
10899                 CHECK_BYTE_COUNT_SUBR(2);
10900                 proto_tree_add_item(
10901                         subtree, hf_smb_ea_data_length, tvb, offset, 2, TRUE);
10902                 COUNT_BYTES_SUBR(2);
10903
10904                 /* EA name */
10905
10906                 name = tvb_get_string(tvb, offset, name_len);
10907                 proto_item_append_text(item, ": %s", name);
10908                 g_free(name);
10909
10910                 CHECK_BYTE_COUNT_SUBR(name_len + 1);
10911                 proto_tree_add_item(
10912                         subtree, hf_smb_ea_name, tvb, offset, name_len + 1, 
10913                         TRUE);
10914                 COUNT_BYTES_SUBR(name_len + 1);
10915
10916                 /* EA data */
10917                 
10918                 CHECK_BYTE_COUNT_SUBR(data_len);
10919                 proto_tree_add_item(
10920                         subtree, hf_smb_ea_data, tvb, offset, data_len, TRUE);
10921                 COUNT_BYTES_SUBR(data_len);
10922
10923                 proto_item_set_len(item, offset - start_offset);
10924         }
10925
10926         *trunc = FALSE;
10927         return offset;
10928 }
10929
10930 /* this dissects the SMB_INFO_IS_NAME_VALID
10931    as described in 4.2.16.3
10932 */
10933 static int
10934 dissect_4_2_16_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10935     int offset, guint16 *bcp, gboolean *trunc)
10936 {
10937         smb_info_t *si = pinfo->private_data;
10938         int fn_len;
10939         const char *fn;
10940
10941         /* file name */
10942         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10943         CHECK_STRING_SUBR(fn);
10944         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10945                 fn);
10946         COUNT_BYTES_SUBR(fn_len);
10947
10948         *trunc = FALSE;
10949         return offset;
10950 }
10951
10952 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
10953    as described in 4.2.16.4
10954 */
10955 static int
10956 dissect_4_2_16_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10957     int offset, guint16 *bcp, gboolean *trunc)
10958 {
10959         /* create time */
10960         CHECK_BYTE_COUNT_SUBR(8);
10961         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
10962         *bcp -= 8;
10963
10964         /* access time */
10965         CHECK_BYTE_COUNT_SUBR(8);
10966         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
10967         *bcp -= 8;
10968
10969         /* last write time */
10970         CHECK_BYTE_COUNT_SUBR(8);
10971         offset = dissect_smb_64bit_time(tvb, tree, offset,
10972                 hf_smb_last_write_time);
10973         *bcp -= 8;
10974
10975         /* last change time */
10976         CHECK_BYTE_COUNT_SUBR(8);
10977         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
10978         *bcp -= 8;
10979
10980         /* File Attributes */
10981         CHECK_BYTE_COUNT_SUBR(4);
10982         offset = dissect_file_attributes(tvb, tree, offset, 4);
10983         *bcp -= 4;
10984
10985         *trunc = FALSE;
10986         return offset;
10987 }
10988
10989 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
10990    as described in 4.2.16.5
10991 */
10992 static int
10993 dissect_4_2_16_5(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10994     int offset, guint16 *bcp, gboolean *trunc)
10995 {
10996         /* allocation size */
10997         CHECK_BYTE_COUNT_SUBR(8);
10998         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10999         COUNT_BYTES_SUBR(8);
11000
11001         /* end of file */
11002         CHECK_BYTE_COUNT_SUBR(8);
11003         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11004         COUNT_BYTES_SUBR(8);
11005
11006         /* number of links */
11007         CHECK_BYTE_COUNT_SUBR(4);
11008         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
11009         COUNT_BYTES_SUBR(4);
11010
11011         /* delete pending */
11012         CHECK_BYTE_COUNT_SUBR(1);
11013         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
11014         COUNT_BYTES_SUBR(1);
11015
11016         /* is directory */
11017         CHECK_BYTE_COUNT_SUBR(1);
11018         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
11019         COUNT_BYTES_SUBR(1);
11020
11021         *trunc = FALSE;
11022         return offset;
11023 }
11024
11025 /* this dissects the SMB_QUERY_FILE_EA_INFO
11026    as described in 4.2.16.6
11027 */
11028 static int
11029 dissect_4_2_16_6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11030     int offset, guint16 *bcp, gboolean *trunc)
11031 {
11032         /* ea length */
11033         CHECK_BYTE_COUNT_SUBR(4);
11034         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11035         COUNT_BYTES_SUBR(4);
11036
11037         *trunc = FALSE;
11038         return offset;
11039 }
11040
11041 /* this dissects the SMB_QUERY_FILE_NAME_INFO
11042    as described in 4.2.16.7
11043    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
11044    as described in 4.2.16.9
11045 */
11046 static int
11047 dissect_4_2_16_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11048     int offset, guint16 *bcp, gboolean *trunc)
11049 {
11050         smb_info_t *si = pinfo->private_data;
11051         int fn_len;
11052         const char *fn;
11053
11054         /* file name len */
11055         CHECK_BYTE_COUNT_SUBR(4);
11056         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
11057         COUNT_BYTES_SUBR(4);
11058
11059         /* file name */
11060         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11061         CHECK_STRING_SUBR(fn);
11062         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11063                 fn);
11064         COUNT_BYTES_SUBR(fn_len);
11065
11066         *trunc = FALSE;
11067         return offset;
11068 }
11069
11070 /* this dissects the SMB_QUERY_FILE_ALL_INFO
11071    as described in 4.2.16.8
11072 */
11073 static int
11074 dissect_4_2_16_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11075     int offset, guint16 *bcp, gboolean *trunc)
11076 {
11077
11078         offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp, trunc);
11079         if (*trunc) {
11080                 return offset;
11081         }
11082         offset = dissect_4_2_16_5(tvb, pinfo, tree, offset, bcp, trunc);
11083         if (*trunc) {
11084                 return offset;
11085         }
11086
11087         /* index number */
11088         CHECK_BYTE_COUNT_SUBR(8);
11089         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
11090         COUNT_BYTES_SUBR(8);
11091
11092         offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp, trunc);
11093         if (*trunc)
11094                 return offset;
11095
11096         /* access flags */
11097         CHECK_BYTE_COUNT_SUBR(4);
11098         offset = dissect_smb_access_mask(tvb, tree, offset);
11099         COUNT_BYTES_SUBR(4);
11100
11101         /* index number */
11102         CHECK_BYTE_COUNT_SUBR(8);
11103         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
11104         COUNT_BYTES_SUBR(8);
11105
11106         /* current offset */
11107         CHECK_BYTE_COUNT_SUBR(8);
11108         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
11109         COUNT_BYTES_SUBR(8);
11110
11111         /* mode */
11112         CHECK_BYTE_COUNT_SUBR(4);
11113         offset = dissect_nt_create_options(tvb, tree, offset);
11114         *bcp -= 4;
11115
11116         /* alignment */
11117         CHECK_BYTE_COUNT_SUBR(4);
11118         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
11119         COUNT_BYTES_SUBR(4);
11120
11121         offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp, trunc);
11122
11123         return offset;
11124 }
11125
11126 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
11127    as described in 4.2.16.10
11128 */
11129 static int
11130 dissect_4_2_16_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11131     int offset, guint16 *bcp, gboolean *trunc)
11132 {
11133         proto_item *item;
11134         proto_tree *tree;
11135         int old_offset;
11136         guint32 neo;
11137         smb_info_t *si = pinfo->private_data;
11138         int fn_len;
11139         const char *fn;
11140         int padcnt;
11141
11142         for (;;) {
11143                 old_offset = offset;
11144
11145                 /* next entry offset */
11146                 CHECK_BYTE_COUNT_SUBR(4);
11147                 if(parent_tree){
11148                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
11149                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11150                 } else {
11151                         item = NULL;
11152                         tree = NULL;
11153                 }
11154
11155                 neo = tvb_get_letohl(tvb, offset);
11156                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11157                 COUNT_BYTES_SUBR(4);
11158
11159                 /* stream name len */
11160                 CHECK_BYTE_COUNT_SUBR(4);
11161                 fn_len = tvb_get_letohl(tvb, offset);
11162                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
11163                 COUNT_BYTES_SUBR(4);
11164
11165                 /* stream size */
11166                 CHECK_BYTE_COUNT_SUBR(8);
11167                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
11168                 COUNT_BYTES_SUBR(8);
11169
11170                 /* allocation size */
11171                 CHECK_BYTE_COUNT_SUBR(8);
11172                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11173                 COUNT_BYTES_SUBR(8);
11174
11175                 /* stream name */
11176                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11177                 CHECK_STRING_SUBR(fn);
11178                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
11179                         fn);
11180                 COUNT_BYTES_SUBR(fn_len);
11181
11182                 proto_item_append_text(item, ": %s", fn);
11183                 proto_item_set_len(item, offset-old_offset);
11184
11185                 if (neo == 0)
11186                         break;  /* no more structures */
11187
11188                 /* skip to next structure */
11189                 padcnt = (old_offset + neo) - offset;
11190                 if (padcnt < 0) {
11191                         /*
11192                          * XXX - this is bogus; flag it?
11193                          */
11194                         padcnt = 0;
11195                 }
11196                 if (padcnt != 0) {
11197                         CHECK_BYTE_COUNT_SUBR(padcnt);
11198                         COUNT_BYTES_SUBR(padcnt);
11199                 }
11200         }
11201
11202         *trunc = FALSE;
11203         return offset;
11204 }
11205
11206 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
11207    as described in 4.2.16.11
11208 */
11209 static int
11210 dissect_4_2_16_11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11211     int offset, guint16 *bcp, gboolean *trunc)
11212 {
11213         /* compressed file size */
11214         CHECK_BYTE_COUNT_SUBR(8);
11215         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
11216         COUNT_BYTES_SUBR(8);
11217
11218         /* compression format */
11219         CHECK_BYTE_COUNT_SUBR(2);
11220         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
11221         COUNT_BYTES_SUBR(2);
11222
11223         /* compression unit shift */
11224         CHECK_BYTE_COUNT_SUBR(1);
11225         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
11226         COUNT_BYTES_SUBR(1);
11227
11228         /* compression chunk shift */
11229         CHECK_BYTE_COUNT_SUBR(1);
11230         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
11231         COUNT_BYTES_SUBR(1);
11232
11233         /* compression cluster shift */
11234         CHECK_BYTE_COUNT_SUBR(1);
11235         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
11236         COUNT_BYTES_SUBR(1);
11237
11238         /* 3 reserved bytes */
11239         CHECK_BYTE_COUNT_SUBR(3);
11240         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
11241         COUNT_BYTES_SUBR(3);
11242
11243         *trunc = FALSE;
11244         return offset;
11245 }
11246
11247 /* 4.2.16.12 - SMB_QUERY_FILE_UNIX_BASIC */
11248
11249 static const value_string unix_file_type_vals[] = {
11250         { 0, "File" },
11251         { 1, "Directory" },
11252         { 2, "Symbolic link" },
11253         { 3, "Character device" },
11254         { 4, "Block device" },
11255         { 5, "FIFO" },
11256         { 6, "Socket" },
11257         { 0, NULL }
11258 };
11259
11260 static int
11261 dissect_4_2_16_12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11262                   int offset, guint16 *bcp, gboolean *trunc)
11263 {
11264         /* End of file (file size) */
11265         CHECK_BYTE_COUNT_SUBR(8);
11266         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
11267         COUNT_BYTES_SUBR(8);
11268
11269         /* Number of bytes */
11270         CHECK_BYTE_COUNT_SUBR(8);
11271         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
11272         COUNT_BYTES_SUBR(8);
11273
11274         /* Last status change */
11275         CHECK_BYTE_COUNT_SUBR(8);
11276         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
11277         *bcp -= 8;              /* dissect_smb_64bit_time() increments offset */
11278
11279         /* Last access time */
11280         CHECK_BYTE_COUNT_SUBR(8);
11281         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
11282         *bcp -= 8;
11283
11284         /* Last modification time */
11285         CHECK_BYTE_COUNT_SUBR(8);
11286         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
11287         *bcp -= 8;
11288
11289         /* File owner uid */
11290         CHECK_BYTE_COUNT_SUBR(8);
11291         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
11292         COUNT_BYTES_SUBR(8);
11293
11294         /* File group gid */
11295         CHECK_BYTE_COUNT_SUBR(8);
11296         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
11297         COUNT_BYTES_SUBR(8);
11298
11299         /* File type */
11300         CHECK_BYTE_COUNT_SUBR(4);
11301         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
11302         COUNT_BYTES_SUBR(4);
11303
11304         /* Major device number */
11305         CHECK_BYTE_COUNT_SUBR(8);
11306         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
11307         COUNT_BYTES_SUBR(8);
11308
11309         /* Minor device number */
11310         CHECK_BYTE_COUNT_SUBR(8);
11311         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
11312         COUNT_BYTES_SUBR(8);
11313
11314         /* Unique id */
11315         CHECK_BYTE_COUNT_SUBR(8);
11316         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
11317         COUNT_BYTES_SUBR(8);
11318
11319         /* Permissions */
11320         CHECK_BYTE_COUNT_SUBR(8);
11321         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
11322         COUNT_BYTES_SUBR(8);
11323
11324         /* Nlinks */
11325         CHECK_BYTE_COUNT_SUBR(8);
11326         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
11327         COUNT_BYTES_SUBR(8);
11328
11329         /* Sometimes there is one extra byte in the data field which I
11330            guess could be padding, but we are only using 4 or 8 byte
11331            data types so this is a bit confusing. -tpot */
11332
11333         *trunc = FALSE;
11334         return offset;
11335 }
11336
11337 /* 4.2.16.13 - SMB_QUERY_FILE_UNIX_LINK */
11338
11339 static int
11340 dissect_4_2_16_13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11341                   int offset, guint16 *bcp, gboolean *trunc)
11342 {
11343         smb_info_t *si = pinfo->private_data;
11344         const char *fn;
11345         int fn_len;
11346
11347         /* Link destination */
11348
11349         fn = get_unicode_or_ascii_string(
11350                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11351
11352         CHECK_STRING_SUBR(fn);
11353         proto_tree_add_string(
11354                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
11355         COUNT_BYTES_SUBR(fn_len);
11356
11357         *trunc = FALSE;
11358         return offset;
11359 }
11360
11361 /* this dissects the SMB_SET_FILE_DISPOSITION_INFO
11362    as described in 4.2.19.2
11363 */
11364 static int
11365 dissect_4_2_19_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11366     int offset, guint16 *bcp, gboolean *trunc)
11367 {
11368         /* marked for deletion? */
11369         CHECK_BYTE_COUNT_SUBR(1);
11370         proto_tree_add_item(tree, hf_smb_t2_marked_for_deletion, tvb, offset, 1, TRUE);
11371         COUNT_BYTES_SUBR(1);
11372
11373         *trunc = FALSE;
11374         return offset;
11375 }
11376
11377 /* this dissects the SMB_SET_FILE_ALLOCATION_INFO
11378    as described in 4.2.19.3
11379 */
11380 static int
11381 dissect_4_2_19_3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11382     int offset, guint16 *bcp, gboolean *trunc)
11383 {
11384         /* file allocation size */
11385         CHECK_BYTE_COUNT_SUBR(8);
11386         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11387         COUNT_BYTES_SUBR(8);
11388
11389         *trunc = FALSE;
11390         return offset;
11391 }
11392
11393 /* this dissects the SMB_SET_FILE_END_OF_FILE_INFO
11394    as described in 4.2.19.4
11395 */
11396 static int
11397 dissect_4_2_19_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11398     int offset, guint16 *bcp, gboolean *trunc)
11399 {
11400         /* file end of file offset */
11401         CHECK_BYTE_COUNT_SUBR(8);
11402         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11403         COUNT_BYTES_SUBR(8);
11404
11405         *trunc = FALSE;
11406         return offset;
11407 }
11408
11409 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION and
11410   TRANS2_QUERY_FILE_INFORMATION*/
11411 static int
11412 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11413     int offset, guint16 *bcp)
11414 {
11415         smb_info_t *si;
11416         gboolean trunc;
11417
11418         if(!*bcp){
11419                 return offset;
11420         }
11421
11422         si = (smb_info_t *)pinfo->private_data;
11423         switch(si->info_level){
11424         case 1:         /*Info Standard*/
11425                 
11426         case 2:         /*Info Query EA Size*/
11427                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
11428                     &trunc);
11429                 break;
11430         case 3:         /*Info Query EAs From List*/
11431         case 4:         /*Info Query All EAs*/
11432                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11433                     &trunc);
11434                 break;
11435         case 6:         /*Info Is Name Valid*/
11436                 offset = dissect_4_2_16_3(tvb, pinfo, tree, offset, bcp,
11437                     &trunc);
11438                 break;
11439         case 0x0101:    /*Query File Basic Info*/
11440         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
11441                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11442                     &trunc);
11443                 break;
11444         case 0x0102:    /*Query File Standard Info*/
11445         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
11446                 offset = dissect_4_2_16_5(tvb, pinfo, tree, offset, bcp,
11447                     &trunc);
11448                 break;
11449         case 0x0103:    /*Query File EA Info*/
11450         case 1007:      /* SMB_FILE_EA_INFORMATION */
11451                 offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp,
11452                     &trunc);
11453                 break;
11454         case 0x0104:    /*Query File Name Info*/
11455         case 1009:      /* SMB_FILE_NAME_INFORMATION */
11456                 offset = dissect_4_2_16_7(tvb, pinfo, tree, offset, bcp,
11457                     &trunc);
11458                 break;
11459         case 0x0107:    /*Query File All Info*/
11460         case 1018:      /* SMB_FILE_ALL_INFORMATION */
11461                 offset = dissect_4_2_16_8(tvb, pinfo, tree, offset, bcp,
11462                     &trunc);
11463                 break;
11464         case 0x0108:    /*Query File Alt File Info*/
11465         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
11466                 offset = dissect_4_2_16_7(tvb, pinfo, tree, offset, bcp,
11467                     &trunc);
11468                 break;
11469         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
11470                 ((smb_info_t *)(pinfo->private_data))->unicode = TRUE;
11471         case 0x0109:    /*Query File Stream Info*/
11472                 offset = dissect_4_2_16_10(tvb, pinfo, tree, offset, bcp,
11473                     &trunc);
11474                 break;
11475         case 0x010b:    /*Query File Compression Info*/
11476         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
11477                 offset = dissect_4_2_16_11(tvb, pinfo, tree, offset, bcp,
11478                     &trunc);
11479                 break;
11480         case 0x0200:    /* Query File Unix Basic*/
11481                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp, 
11482                                            &trunc);
11483                 break;
11484         case 0x0201:    /* Query File Unix Link*/
11485                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp, 
11486                                            &trunc);
11487                 break;
11488         case 0x0202:    /* Query File Unix HardLink*/
11489                 /* XXX add this from the SNIA doc */
11490                 break;
11491         }
11492
11493         return offset;
11494 }
11495
11496 /*dissect the data block for TRANS2_SET_PATH_INFORMATION and
11497   TRANS2_SET_FILE_INFORMATION*/
11498 static int
11499 dissect_spi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11500     int offset, guint16 *bcp)
11501 {
11502         smb_info_t *si;
11503         gboolean trunc;
11504
11505         if(!*bcp){
11506                 return offset;
11507         }
11508
11509         si = (smb_info_t *)pinfo->private_data;
11510         switch(si->info_level){
11511         case 1:         /*Info Standard*/
11512                 
11513         case 2:         /*Info Query EA Size*/
11514                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
11515                     &trunc);
11516                 break;
11517         case 4:         /*Info Query All EAs*/
11518                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11519                     &trunc);
11520                 break;
11521         case 0x0101:    /*Set File Basic Info*/
11522                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11523                     &trunc);
11524                 break;
11525         case 0x0102:    /*Set File Disposition Info*/
11526                 offset = dissect_4_2_19_2(tvb, pinfo, tree, offset, bcp,
11527                     &trunc);
11528                 break;
11529         case 0x0103:    /*Set File Allocation Info*/
11530                 offset = dissect_4_2_19_3(tvb, pinfo, tree, offset, bcp,
11531                     &trunc);
11532                 break;
11533         case 0x0104:    /*Set End Of File Info*/
11534                 offset = dissect_4_2_19_4(tvb, pinfo, tree, offset, bcp,
11535                     &trunc);
11536                 break;
11537         case 0x0200:    /*Set File Unix Basic.  Same as query. */
11538                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
11539                     &trunc);
11540                 break;
11541         case 0x0201:    /*Set File Unix Link.  Same as query. */
11542                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
11543                     &trunc);
11544                 break;
11545         case 0x0203:    /*Set File Unix HardLink.  Same as link query. */
11546                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
11547                     &trunc);
11548                 break;
11549         case 1004:
11550                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11551                     &trunc);
11552                 break;
11553         case 1010:
11554         case 1013:
11555         case 1014:
11556         case 1016:
11557         case 1019:
11558         case 1020:
11559         case 1023:
11560         case 1025:
11561         case 1029:
11562         case 1032:
11563         case 1039:
11564         case 1040:
11565                 /* XXX: TODO, extra levels discovered by tridge */
11566                 break;
11567         }
11568
11569         return offset;
11570 }
11571
11572
11573 static const true_false_string tfs_quota_flags_deny_disk = {
11574         "DENY DISK SPACE for users exceeding quota limit",
11575         "Do NOT deny disk space for users exceeding quota limit"
11576 };
11577 static const true_false_string tfs_quota_flags_log_limit = {
11578         "LOG EVENT when a user exceeds their QUOTA LIMIT",
11579         "Do NOT log event when a user exceeds their quota limit"
11580 };
11581 static const true_false_string tfs_quota_flags_log_warning = {
11582         "LOG EVENT when a user exceeds their WARNING LEVEL",
11583         "Do NOT log event when a user exceeds their warning level"
11584 };
11585 static const true_false_string tfs_quota_flags_enabled = {
11586         "Quotas are ENABLED of this fs",
11587         "Quotas are NOT enabled on this fs"
11588 };
11589 static void
11590 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11591 {
11592         guint8 mask;
11593         proto_item *item = NULL;
11594         proto_tree *tree = NULL;
11595
11596         mask = tvb_get_guint8(tvb, offset);
11597
11598         if(parent_tree){
11599                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
11600                         "Quota Flags: 0x%02x %s", mask,
11601                         mask?"Enabled":"Disabled");
11602                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
11603         }
11604
11605         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
11606                 tvb, offset, 1, mask);
11607         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
11608                 tvb, offset, 1, mask);
11609         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
11610                 tvb, offset, 1, mask);
11611
11612         if(mask && (!(mask&0x01))){
11613                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
11614                         tvb, offset, 1, 0x01);
11615         } else {
11616                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
11617                         tvb, offset, 1, mask);
11618         }
11619
11620 }
11621
11622 static int
11623 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
11624 {
11625         /* first 24 bytes are unknown */
11626         CHECK_BYTE_COUNT_TRANS_SUBR(24);
11627         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11628                     offset, 24, TRUE);
11629         COUNT_BYTES_TRANS_SUBR(24);
11630
11631         /* number of bytes for quota warning */
11632         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11633         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
11634         COUNT_BYTES_TRANS_SUBR(8);
11635
11636         /* number of bytes for quota limit */
11637         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11638         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
11639         COUNT_BYTES_TRANS_SUBR(8);
11640
11641         /* one byte of quota flags */
11642         CHECK_BYTE_COUNT_TRANS_SUBR(1);
11643         dissect_quota_flags(tvb, tree, offset);
11644         COUNT_BYTES_TRANS_SUBR(1);
11645
11646         /* these 7 bytes are unknown */
11647         CHECK_BYTE_COUNT_TRANS_SUBR(7);
11648         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11649                     offset, 7, TRUE);
11650         COUNT_BYTES_TRANS_SUBR(7);
11651
11652         return offset;
11653 }
11654
11655 static int
11656 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
11657     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
11658 {
11659         proto_item *item = NULL;
11660         proto_tree *tree = NULL;
11661         smb_info_t *si;
11662
11663         si = (smb_info_t *)pinfo->private_data;
11664
11665         if(parent_tree){
11666                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
11667                                 "%s Data",
11668                                 val_to_str(subcmd, trans2_cmd_vals,
11669                                                 "Unknown (0x%02x)"));
11670                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
11671         }
11672
11673         switch(subcmd){
11674         case 0x00:      /*TRANS2_OPEN2*/
11675                 /* XXX dont know how to decode FEAList */
11676                 break;
11677         case 0x01:      /*TRANS2_FIND_FIRST2*/
11678                 /* XXX dont know how to decode FEAList */
11679                 break;
11680         case 0x02:      /*TRANS2_FIND_NEXT2*/
11681                 /* XXX dont know how to decode FEAList */
11682                 break;
11683         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
11684                 /* no data field in this request */
11685                 break;
11686         case 0x04:      /* TRANS2_SET_QUOTA */
11687                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
11688                 break;
11689         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
11690                 /* no data field in this request */
11691                 /*
11692                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11693                  * Extensions Version 3.0, Document Version 1.11,
11694                  * July 19, 1990" says there may be "Additional
11695                  * FileInfoLevel dependent information" here.
11696                  *
11697                  * Was that just a cut-and-pasteo?
11698                  * TRANS2_SET_PATH_INFORMATION *does* have that information
11699                  * here.
11700                  */
11701                 break;
11702         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
11703                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
11704                 break;
11705         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
11706                 /* no data field in this request */
11707                 /*
11708                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11709                  * Extensions Version 3.0, Document Version 1.11,
11710                  * July 19, 1990" says there may be "Additional
11711                  * FileInfoLevel dependent information" here.
11712                  *
11713                  * Was that just a cut-and-pasteo?
11714                  * TRANS2_SET_FILE_INFORMATION *does* have that information
11715                  * here.
11716                  */
11717                 break;
11718         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
11719                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
11720                 break;
11721         case 0x09:      /*TRANS2_FSCTL*/
11722                 /*XXX dont know how to decode this yet */
11723
11724                 /*
11725                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11726                  * Extensions Version 3.0, Document Version 1.11,
11727                  * July 19, 1990" says this this contains a
11728                  * "File system specific data block".  (That means we
11729                  * may not be able to dissect it in any case.)
11730                  */
11731                 break;
11732         case 0x0a:      /*TRANS2_IOCTL2*/
11733                 /*XXX dont know how to decode this yet */
11734
11735                 /*
11736                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11737                  * Extensions Version 3.0, Document Version 1.11,
11738                  * July 19, 1990" says this this contains a
11739                  * "Device/function specific data block".  (That
11740                  * means we may not be able to dissect it in any case.)
11741                  */
11742                 break;
11743         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11744                 /*XXX dont know how to decode this yet */
11745
11746                 /*
11747                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11748                  * Extensions Version 3.0, Document Version 1.11,
11749                  * July 19, 1990" says this this contains "additional
11750                  * level dependent match data".
11751                  */
11752                 break;
11753         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11754                 /*XXX dont know how to decode this yet */
11755
11756                 /*
11757                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11758                  * Extensions Version 3.0, Document Version 1.11,
11759                  * July 19, 1990" says this this contains "additional
11760                  * level dependent monitor information".
11761                  */
11762                 break;
11763         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11764                 /* XXX optional FEAList, unknown what FEAList looks like*/
11765                 break;
11766         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11767                 /*XXX dont know how to decode this yet */
11768                 break;
11769         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11770                 /* no data field in this request */
11771                 break;
11772         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11773                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
11774                 break;
11775         }
11776
11777         /* ooops there were data we didnt know how to process */
11778         if(dc != 0){
11779                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
11780                 offset += dc;
11781         }
11782
11783         return offset;
11784 }
11785
11786
11787 static void
11788 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
11789     proto_tree *tree)
11790 {
11791         int i;
11792         int offset;
11793         guint length;
11794
11795         /*
11796          * Show the setup words.
11797          */
11798         if (s_tvb != NULL) {
11799                 length = tvb_reported_length(s_tvb);
11800                 for (i = 0, offset = 0; length >= 2;
11801                     i++, offset += 2, length -= 2) {
11802                         /*
11803                          * XXX - add a setup word filterable field?
11804                          */
11805                         proto_tree_add_text(tree, s_tvb, offset, 2,
11806                             "Setup Word %d: 0x%04x", i,
11807                             tvb_get_letohs(s_tvb, offset));
11808                 }
11809         }
11810
11811         /*
11812          * Show the parameters, if any.
11813          */
11814         if (p_tvb != NULL) {
11815                 length = tvb_reported_length(p_tvb);
11816                 if (length != 0) {
11817                         proto_tree_add_text(tree, p_tvb, 0, length,
11818                             "Parameters: %s",
11819                             tvb_bytes_to_str(p_tvb, 0, length));
11820                 }
11821         }
11822
11823         /*
11824          * Show the data, if any.
11825          */
11826         if (d_tvb != NULL) {
11827                 length = tvb_reported_length(d_tvb);
11828                 if (length != 0) {
11829                         proto_tree_add_text(tree, d_tvb, 0, length,
11830                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
11831                 }
11832         }
11833 }
11834
11835 /* This routine handles the following 4 calls
11836    Transaction  0x25
11837    Transaction Secondary 0x26
11838    Transaction2 0x32
11839    Transaction2 Secondary 0x33
11840 */
11841 static int
11842 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
11843 {
11844         guint8 wc, sc=0;
11845         int so=offset;
11846         int sl=0;
11847         int spo=offset;
11848         int spc=0;
11849         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
11850         int subcmd = -1;
11851         guint32 to;
11852         int an_len;
11853         const char *an = NULL;
11854         smb_info_t *si;
11855         smb_transact2_info_t *t2i;
11856         smb_transact_info_t *tri;
11857         guint16 bc;
11858         int padcnt;
11859         gboolean dissected_trans;
11860
11861         si = (smb_info_t *)pinfo->private_data;
11862
11863         WORD_COUNT;
11864
11865         if(wc==8){
11866                 /*secondary client request*/
11867
11868                 /* total param count, only a 16bit integer here*/
11869                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11870                 offset += 2;
11871
11872                 /* total data count , only 16bit integer here*/
11873                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11874                 offset += 2;
11875
11876                 /* param count */
11877                 pc = tvb_get_letohs(tvb, offset);
11878                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11879                 offset += 2;
11880
11881                 /* param offset */
11882                 po = tvb_get_letohs(tvb, offset);
11883                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11884                 offset += 2;
11885
11886                 /* param disp */
11887                 pd = tvb_get_letohs(tvb, offset);
11888                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
11889                 offset += 2;
11890
11891                 /* data count */
11892                 dc = tvb_get_letohs(tvb, offset);
11893                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11894                 offset += 2;
11895
11896                 /* data offset */
11897                 od = tvb_get_letohs(tvb, offset);
11898                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11899                 offset += 2;
11900
11901                 /* data disp */
11902                 dd = tvb_get_letohs(tvb, offset);
11903                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
11904                 offset += 2;
11905
11906                 if(si->cmd==SMB_COM_TRANSACTION2){
11907                         guint16 fid;
11908
11909                         /* fid */
11910                         fid = tvb_get_letohs(tvb, offset);
11911                         add_fid(tvb, pinfo, tree, offset, 2, fid);
11912
11913                         offset += 2;
11914                 }
11915
11916                 /* There are no setup words. */
11917                 so = offset;
11918                 sc = 0;
11919                 sl = 0;
11920         } else {
11921                 /* it is not a secondary request */
11922
11923                 /* total param count , only a 16 bit integer here*/
11924                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11925                 offset += 2;
11926
11927                 /* total data count , only 16bit integer here*/
11928                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11929                 offset += 2;
11930
11931                 /* max param count , only 16bit integer here*/
11932                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11933                 offset += 2;
11934
11935                 /* max data count, only 16bit integer here*/
11936                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11937                 offset += 2;
11938
11939                 /* max setup count, only 16bit integer here*/
11940                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
11941                 offset += 1;
11942
11943                 /* reserved byte */
11944                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11945                 offset += 1;
11946
11947                 /* transaction flags */
11948                 tf = dissect_transaction_flags(tvb, tree, offset);
11949                 offset += 2;
11950
11951                 /* timeout */
11952                 to = tvb_get_letohl(tvb, offset);
11953                 if (to == 0)
11954                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
11955                 else if (to == 0xffffffff)
11956                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
11957                 else
11958                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
11959                 offset += 4;
11960
11961                 /* 2 reserved bytes */
11962                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
11963                 offset += 2;
11964
11965                 /* param count */
11966                 pc = tvb_get_letohs(tvb, offset);
11967                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11968                 offset += 2;
11969
11970                 /* param offset */
11971                 po = tvb_get_letohs(tvb, offset);
11972                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11973                 offset += 2;
11974
11975                 /* param displacement is zero here */
11976                 pd = 0;
11977
11978                 /* data count */
11979                 dc = tvb_get_letohs(tvb, offset);
11980                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11981                 offset += 2;
11982
11983                 /* data offset */
11984                 od = tvb_get_letohs(tvb, offset);
11985                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11986                 offset += 2;
11987
11988                 /* data displacement is zero here */
11989                 dd = 0;
11990
11991                 /* setup count */
11992                 sc = tvb_get_guint8(tvb, offset);
11993                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
11994                 offset += 1;
11995
11996                 /* reserved byte */
11997                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11998                 offset += 1;
11999
12000                 /* this is where the setup bytes, if any start */
12001                 so = offset;
12002                 sl = sc*2;
12003
12004                 /* if there were any setup bytes, decode them */
12005                 if(sc){
12006                         switch(si->cmd){
12007
12008                         case SMB_COM_TRANSACTION2:
12009                                 /* TRANSACTION2 only has one setup word and
12010                                    that is the subcommand code.
12011
12012                                    XXX - except for TRANS2_FSCTL
12013                                    and TRANS2_IOCTL. */
12014                                 subcmd = tvb_get_letohs(tvb, offset);
12015                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
12016                                     tvb, offset, 2, subcmd);
12017                                 if (check_col(pinfo->cinfo, COL_INFO)) {
12018                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
12019                                             val_to_str(subcmd, trans2_cmd_vals,
12020                                                 "Unknown (0x%02x)"));
12021                                 }
12022                                 if (!si->unidir) {
12023                                         if(!pinfo->fd->flags.visited){
12024                                                 /*
12025                                                  * Allocate a new
12026                                                  * smb_transact2_info_t
12027                                                  * structure.
12028                                                  */
12029                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
12030                                                 t2i->subcmd = subcmd;
12031                                                 t2i->info_level = -1;
12032                                                 t2i->resume_keys = FALSE;
12033                                                 si->sip->extra_info = t2i;
12034                                         }
12035                                 }
12036
12037                                 /*
12038                                  * XXX - process TRANS2_FSCTL and
12039                                  * TRANS2_IOCTL setup words here.
12040                                  */
12041                                 break;
12042
12043                         case SMB_COM_TRANSACTION:
12044                                 /* TRANSACTION setup words processed below */
12045                                 break;
12046                         }
12047
12048                         offset += sl;
12049                 }
12050         }
12051
12052         BYTE_COUNT;
12053
12054         if(wc!=8){
12055                 /* primary request */
12056                 /* name is NULL if transaction2 */
12057                 if(si->cmd == SMB_COM_TRANSACTION){
12058                         /* Transaction Name */
12059                         an = get_unicode_or_ascii_string(tvb, &offset,
12060                                 si->unicode, &an_len, FALSE, FALSE, &bc);
12061                         if (an == NULL)
12062                                 goto endofcommand;
12063                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
12064                                 offset, an_len, an);
12065                         COUNT_BYTES(an_len);
12066                 }
12067         }
12068
12069         /*
12070          * The pipe or mailslot arguments for Transaction start with
12071          * the first setup word (or where the first setup word would
12072          * be if there were any setup words), and run to the current
12073          * offset (which could mean that there aren't any).
12074          */
12075         spo = so;
12076         spc = offset - spo;
12077
12078         /* parameters */
12079         if(po>offset){
12080                 /* We have some initial padding bytes.
12081                 */
12082                 padcnt = po-offset;
12083                 if (padcnt > bc)
12084                         padcnt = bc;
12085                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12086                 COUNT_BYTES(padcnt);
12087         }
12088         if(pc){
12089                 CHECK_BYTE_COUNT(pc);
12090                 switch(si->cmd) {
12091
12092                 case SMB_COM_TRANSACTION2:
12093                         /* TRANSACTION2 parameters*/
12094                         offset = dissect_transaction2_request_parameters(tvb,
12095                             pinfo, tree, offset, subcmd, pc);
12096                         bc -= pc;
12097                         break;
12098
12099                 case SMB_COM_TRANSACTION:
12100                         /* TRANSACTION parameters processed below */
12101                         COUNT_BYTES(pc);
12102                         break;
12103                 }
12104         }
12105
12106         /* data */
12107         if(od>offset){
12108                 /* We have some initial padding bytes.
12109                 */
12110                 padcnt = od-offset;
12111                 if (padcnt > bc)
12112                         padcnt = bc;
12113                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12114                 COUNT_BYTES(padcnt);
12115         }
12116         if(dc){
12117                 CHECK_BYTE_COUNT(dc);
12118                 switch(si->cmd){
12119
12120                 case SMB_COM_TRANSACTION2:
12121                         /* TRANSACTION2 data*/
12122                         offset = dissect_transaction2_request_data(tvb, pinfo,
12123                             tree, offset, subcmd, dc);
12124                         bc -= dc;
12125                         break;
12126
12127                 case SMB_COM_TRANSACTION:
12128                         /* TRANSACTION data processed below */
12129                         COUNT_BYTES(dc);
12130                         break;
12131                 }
12132         }
12133
12134         /*TRANSACTION request parameters */
12135         if(si->cmd==SMB_COM_TRANSACTION){
12136                 /*XXX replace this block with a function and use that one
12137                      for both requests/responses*/
12138                 if(dd==0){
12139                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
12140                         tvbuff_t *sp_tvb, *pd_tvb;
12141
12142                         if(pc>0){
12143                                 if(pc>tvb_length_remaining(tvb, po)){
12144                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
12145                                 } else {
12146                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
12147                                 }
12148                         } else {
12149                                 p_tvb = NULL;
12150                         }
12151                         if(dc>0){
12152                                 if(dc>tvb_length_remaining(tvb, od)){
12153                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
12154                                 } else {
12155                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
12156                                 }
12157                         } else {
12158                                 d_tvb = NULL;
12159                         }
12160                         if(sl){
12161                                 if(sl>tvb_length_remaining(tvb, so)){
12162                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
12163                                 } else {
12164                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
12165                                 }
12166                         } else {
12167                                 s_tvb = NULL;
12168                         }
12169
12170                         if (!si->unidir) {
12171                                 if(!pinfo->fd->flags.visited){
12172                                         /*
12173                                          * Allocate a new smb_transact_info_t
12174                                          * structure.
12175                                          */
12176                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
12177                                         tri->subcmd = -1;
12178                                         tri->trans_subcmd = -1;
12179                                         tri->function = -1;
12180                                         tri->fid = -1;
12181                                         tri->lanman_cmd = 0;
12182                                         tri->param_descrip = NULL;
12183                                         tri->data_descrip = NULL;
12184                                         tri->aux_data_descrip = NULL;
12185                                         tri->info_level = -1;
12186                                         si->sip->extra_info = tri;
12187                                 } else {
12188                                         /*
12189                                          * We already filled the structure
12190                                          * in; don't bother doing so again.
12191                                          */
12192                                         tri = NULL;
12193                                 }
12194                         } else {
12195                                 /*
12196                                  * This is a unidirectional message, for
12197                                  * which there will be no reply; don't
12198                                  * bother allocating an "smb_transact_info_t"
12199                                  * structure for it.
12200                                  */
12201                                 tri = NULL;
12202                         }
12203                         dissected_trans = FALSE;
12204                         if(strncmp("\\PIPE\\", an, 6) == 0){
12205                                 if (tri != NULL)
12206                                         tri->subcmd=TRANSACTION_PIPE;
12207
12208                                 /*
12209                                  * A tvbuff containing the setup words and
12210                                  * the pipe path.
12211                                  */
12212                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
12213
12214                                 /*
12215                                  * A tvbuff containing the parameters and the
12216                                  * data.
12217                                  */
12218                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
12219
12220                                 dissected_trans = dissect_pipe_smb(sp_tvb,
12221                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
12222                                     top_tree);
12223
12224                                 /* In case we did not see the TreeConnect call,
12225                                    store this TID here as well as a IPC TID 
12226                                    so we know that future Read/Writes to this 
12227                                    TID is (probably) DCERPC.
12228                                 */
12229                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
12230                                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
12231                                 }
12232                                 g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
12233                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
12234                                 if (tri != NULL)
12235                                         tri->subcmd=TRANSACTION_MAILSLOT;
12236
12237                                 /*
12238                                  * A tvbuff containing the setup words and
12239                                  * the mailslot path.
12240                                  */
12241                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
12242                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
12243                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
12244                         }
12245                         if (!dissected_trans)
12246                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
12247                 } else {
12248                         if(check_col(pinfo->cinfo, COL_INFO)){
12249                                 col_append_str(pinfo->cinfo, COL_INFO,
12250                                         "[transact continuation]");
12251                         }
12252                 }
12253         }
12254
12255         END_OF_SMB
12256
12257         return offset;
12258 }
12259
12260
12261
12262 static int
12263 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12264     int offset, guint16 *bcp, gboolean *trunc)
12265 {
12266         int fn_len;
12267         const char *fn;
12268         int old_offset = offset;
12269         proto_item *item = NULL;
12270         proto_tree *tree = NULL;
12271         smb_info_t *si;
12272         smb_transact2_info_t *t2i;
12273         gboolean resume_keys = FALSE;
12274
12275         si = (smb_info_t *)pinfo->private_data;
12276         if (si->sip != NULL) {
12277                 t2i = si->sip->extra_info;
12278                 if (t2i != NULL)
12279                         resume_keys = t2i->resume_keys;
12280         }
12281
12282         if(parent_tree){
12283                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12284                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12285                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12286         }
12287
12288         if (resume_keys) {
12289                 /* resume key */
12290                 CHECK_BYTE_COUNT_SUBR(4);
12291                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
12292                 COUNT_BYTES_SUBR(4);
12293         }
12294
12295         /* create time */
12296         CHECK_BYTE_COUNT_SUBR(4);
12297         offset = dissect_smb_datetime(tvb, tree, offset,
12298                 hf_smb_create_time,
12299                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
12300         *bcp -= 4;
12301
12302         /* access time */
12303         CHECK_BYTE_COUNT_SUBR(4);
12304         offset = dissect_smb_datetime(tvb, tree, offset,
12305                 hf_smb_access_time,
12306                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
12307         *bcp -= 4;
12308
12309         /* last write time */
12310         CHECK_BYTE_COUNT_SUBR(4);
12311         offset = dissect_smb_datetime(tvb, tree, offset,
12312                 hf_smb_last_write_time,
12313                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
12314         *bcp -= 4;
12315
12316         /* data size */
12317         CHECK_BYTE_COUNT_SUBR(4);
12318         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12319         COUNT_BYTES_SUBR(4);
12320
12321         /* allocation size */
12322         CHECK_BYTE_COUNT_SUBR(4);
12323         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
12324         COUNT_BYTES_SUBR(4);
12325
12326         /* File Attributes */
12327         CHECK_BYTE_COUNT_SUBR(2);
12328         offset = dissect_file_attributes(tvb, tree, offset, 2);
12329         *bcp -= 2;
12330
12331         /* file name len */
12332         CHECK_BYTE_COUNT_SUBR(1);
12333         fn_len = tvb_get_guint8(tvb, offset);
12334         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
12335         COUNT_BYTES_SUBR(1);
12336         if (si->unicode)
12337                 fn_len += 2;    /* include terminating '\0' */
12338         else
12339                 fn_len++;       /* include terminating '\0' */
12340
12341         /* file name */
12342         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12343         CHECK_STRING_SUBR(fn);
12344         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12345                 fn);
12346         COUNT_BYTES_SUBR(fn_len);
12347
12348         if (check_col(pinfo->cinfo, COL_INFO)) {
12349                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12350                 fn);
12351         }
12352
12353         proto_item_append_text(item, " File: %s", fn);
12354         proto_item_set_len(item, offset-old_offset);
12355
12356         *trunc = FALSE;
12357         return offset;
12358 }
12359
12360 static int
12361 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12362     int offset, guint16 *bcp, gboolean *trunc)
12363 {
12364         int fn_len;
12365         const char *fn;
12366         int old_offset = offset;
12367         proto_item *item = NULL;
12368         proto_tree *tree = NULL;
12369         smb_info_t *si;
12370         smb_transact2_info_t *t2i;
12371         gboolean resume_keys = FALSE;
12372
12373         si = (smb_info_t *)pinfo->private_data;
12374         if (si->sip != NULL) {
12375                 t2i = si->sip->extra_info;
12376                 if (t2i != NULL)
12377                         resume_keys = t2i->resume_keys;
12378         }
12379
12380         if(parent_tree){
12381                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12382                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12383                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12384         }
12385
12386         if (resume_keys) {
12387                 /* resume key */
12388                 CHECK_BYTE_COUNT_SUBR(4);
12389                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
12390                 COUNT_BYTES_SUBR(4);
12391         }
12392
12393         /* create time */
12394         CHECK_BYTE_COUNT_SUBR(4);
12395         offset = dissect_smb_datetime(tvb, tree, offset,
12396                 hf_smb_create_time,
12397                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
12398         *bcp -= 4;
12399
12400         /* access time */
12401         CHECK_BYTE_COUNT_SUBR(4);
12402         offset = dissect_smb_datetime(tvb, tree, offset,
12403                 hf_smb_access_time,
12404                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
12405         *bcp -= 4;
12406
12407         /* last write time */
12408         CHECK_BYTE_COUNT_SUBR(4);
12409         offset = dissect_smb_datetime(tvb, tree, offset,
12410                 hf_smb_last_write_time,
12411                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
12412         *bcp -= 4;
12413
12414         /* data size */
12415         CHECK_BYTE_COUNT_SUBR(4);
12416         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12417         COUNT_BYTES_SUBR(4);
12418
12419         /* allocation size */
12420         CHECK_BYTE_COUNT_SUBR(4);
12421         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
12422         COUNT_BYTES_SUBR(4);
12423
12424         /* File Attributes */
12425         CHECK_BYTE_COUNT_SUBR(2);
12426         offset = dissect_file_attributes(tvb, tree, offset, 2);
12427         *bcp -= 2;
12428
12429         /* ea length */
12430         CHECK_BYTE_COUNT_SUBR(4);
12431         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12432         COUNT_BYTES_SUBR(4);
12433
12434         /* file name len */
12435         CHECK_BYTE_COUNT_SUBR(1);
12436         fn_len = tvb_get_guint8(tvb, offset);
12437         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
12438         COUNT_BYTES_SUBR(1);
12439         if (si->unicode)
12440                 fn_len += 2;    /* include terminating '\0' */
12441         else
12442                 fn_len++;       /* include terminating '\0' */
12443
12444         /* file name */
12445         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12446         CHECK_STRING_SUBR(fn);
12447         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12448                 fn);
12449         COUNT_BYTES_SUBR(fn_len);
12450
12451         if (check_col(pinfo->cinfo, COL_INFO)) {
12452                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12453                 fn);
12454         }
12455
12456         proto_item_append_text(item, " File: %s", fn);
12457         proto_item_set_len(item, offset-old_offset);
12458
12459         *trunc = FALSE;
12460         return offset;
12461 }
12462
12463 static int
12464 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12465     int offset, guint16 *bcp, gboolean *trunc)
12466 {
12467         int fn_len;
12468         const char *fn;
12469         int old_offset = offset;
12470         proto_item *item = NULL;
12471         proto_tree *tree = NULL;
12472         smb_info_t *si;
12473         guint32 neo;
12474         int padcnt;
12475
12476         si = (smb_info_t *)pinfo->private_data;
12477
12478         if(parent_tree){
12479                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12480                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12481                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12482         }
12483
12484         /*
12485          * We assume that the presence of a next entry offset implies the
12486          * absence of a resume key, as appears to be the case for 4.3.4.6.
12487          */
12488
12489         /* next entry offset */
12490         CHECK_BYTE_COUNT_SUBR(4);
12491         neo = tvb_get_letohl(tvb, offset);
12492         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12493         COUNT_BYTES_SUBR(4);
12494
12495         /* file index */
12496         CHECK_BYTE_COUNT_SUBR(4);
12497         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12498         COUNT_BYTES_SUBR(4);
12499
12500         /* create time */
12501         CHECK_BYTE_COUNT_SUBR(8);
12502         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12503         *bcp -= 8;
12504
12505         /* access time */
12506         CHECK_BYTE_COUNT_SUBR(8);
12507         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12508         *bcp -= 8;
12509
12510         /* last write time */
12511         CHECK_BYTE_COUNT_SUBR(8);
12512         offset = dissect_smb_64bit_time(tvb, tree, offset,
12513                 hf_smb_last_write_time);
12514         *bcp -= 8;
12515
12516         /* last change time */
12517         CHECK_BYTE_COUNT_SUBR(8);
12518         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12519         *bcp -= 8;
12520
12521         /* end of file */
12522         CHECK_BYTE_COUNT_SUBR(8);
12523         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12524         COUNT_BYTES_SUBR(8);
12525
12526         /* allocation size */
12527         CHECK_BYTE_COUNT_SUBR(8);
12528         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12529         COUNT_BYTES_SUBR(8);
12530
12531         /* Extended File Attributes */
12532         CHECK_BYTE_COUNT_SUBR(4);
12533         offset = dissect_file_ext_attr(tvb, tree, offset);
12534         *bcp -= 4;
12535
12536         /* file name len */
12537         CHECK_BYTE_COUNT_SUBR(4);
12538         fn_len = tvb_get_letohl(tvb, offset);
12539         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12540         COUNT_BYTES_SUBR(4);
12541
12542         /* file name */
12543         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12544         CHECK_STRING_SUBR(fn);
12545         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12546                 fn);
12547         COUNT_BYTES_SUBR(fn_len);
12548
12549         if (check_col(pinfo->cinfo, COL_INFO)) {
12550                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12551                 fn);
12552         }
12553
12554         /* skip to next structure */
12555         if(neo){
12556                 padcnt = (old_offset + neo) - offset;
12557                 if (padcnt < 0) {
12558                         /*
12559                          * XXX - this is bogus; flag it?
12560                          */
12561                         padcnt = 0;
12562                 }
12563                 if (padcnt != 0) {
12564                         CHECK_BYTE_COUNT_SUBR(padcnt);
12565                         COUNT_BYTES_SUBR(padcnt);
12566                 }
12567         }
12568
12569         proto_item_append_text(item, " File: %s", fn);
12570         proto_item_set_len(item, offset-old_offset);
12571
12572         *trunc = FALSE;
12573         return offset;
12574 }
12575
12576 static int
12577 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12578     int offset, guint16 *bcp, gboolean *trunc)
12579 {
12580         int fn_len;
12581         const char *fn;
12582         int old_offset = offset;
12583         proto_item *item = NULL;
12584         proto_tree *tree = NULL;
12585         smb_info_t *si;
12586         guint32 neo;
12587         int padcnt;
12588
12589         si = (smb_info_t *)pinfo->private_data;
12590
12591         if(parent_tree){
12592                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12593                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12594                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12595         }
12596
12597         /*
12598          * We assume that the presence of a next entry offset implies the
12599          * absence of a resume key, as appears to be the case for 4.3.4.6.
12600          */
12601
12602         /* next entry offset */
12603         CHECK_BYTE_COUNT_SUBR(4);
12604         neo = tvb_get_letohl(tvb, offset);
12605         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12606         COUNT_BYTES_SUBR(4);
12607
12608         /* file index */
12609         CHECK_BYTE_COUNT_SUBR(4);
12610         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12611         COUNT_BYTES_SUBR(4);
12612
12613         /* create time */
12614         CHECK_BYTE_COUNT_SUBR(8);
12615         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12616         *bcp -= 8;
12617
12618         /* access time */
12619         CHECK_BYTE_COUNT_SUBR(8);
12620         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12621         *bcp -= 8;
12622
12623         /* last write time */
12624         CHECK_BYTE_COUNT_SUBR(8);
12625         offset = dissect_smb_64bit_time(tvb, tree, offset,
12626                 hf_smb_last_write_time);
12627         *bcp -= 8;
12628
12629         /* last change time */
12630         CHECK_BYTE_COUNT_SUBR(8);
12631         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12632         *bcp -= 8;
12633
12634         /* end of file */
12635         CHECK_BYTE_COUNT_SUBR(8);
12636         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12637         COUNT_BYTES_SUBR(8);
12638
12639         /* allocation size */
12640         CHECK_BYTE_COUNT_SUBR(8);
12641         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12642         COUNT_BYTES_SUBR(8);
12643
12644         /* Extended File Attributes */
12645         CHECK_BYTE_COUNT_SUBR(4);
12646         offset = dissect_file_ext_attr(tvb, tree, offset);
12647         *bcp -= 4;
12648
12649         /* file name len */
12650         CHECK_BYTE_COUNT_SUBR(4);
12651         fn_len = tvb_get_letohl(tvb, offset);
12652         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12653         COUNT_BYTES_SUBR(4);
12654
12655         /* ea length */
12656         CHECK_BYTE_COUNT_SUBR(4);
12657         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12658         COUNT_BYTES_SUBR(4);
12659
12660         /* file name */
12661         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12662         CHECK_STRING_SUBR(fn);
12663         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12664                 fn);
12665         COUNT_BYTES_SUBR(fn_len);
12666
12667         if (check_col(pinfo->cinfo, COL_INFO)) {
12668                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12669                 fn);
12670         }
12671
12672         /* skip to next structure */
12673         if(neo){
12674                 padcnt = (old_offset + neo) - offset;
12675                 if (padcnt < 0) {
12676                         /*
12677                          * XXX - this is bogus; flag it?
12678                          */
12679                         padcnt = 0;
12680                 }
12681                 if (padcnt != 0) {
12682                         CHECK_BYTE_COUNT_SUBR(padcnt);
12683                         COUNT_BYTES_SUBR(padcnt);
12684                 }
12685         }
12686
12687         proto_item_append_text(item, " File: %s", fn);
12688         proto_item_set_len(item, offset-old_offset);
12689
12690         *trunc = FALSE;
12691         return offset;
12692 }
12693
12694 static int
12695 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12696     int offset, guint16 *bcp, gboolean *trunc)
12697 {
12698         int fn_len, sfn_len;
12699         const char *fn, *sfn;
12700         int old_offset = offset;
12701         proto_item *item = NULL;
12702         proto_tree *tree = NULL;
12703         smb_info_t *si;
12704         guint32 neo;
12705         int padcnt;
12706
12707         si = (smb_info_t *)pinfo->private_data;
12708
12709         if(parent_tree){
12710                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12711                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12712                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12713         }
12714
12715         /*
12716          * XXX - I have not seen any of these that contain a resume
12717          * key, even though some of the requests had the "return resume
12718          * key" flag set.
12719          */
12720
12721         /* next entry offset */
12722         CHECK_BYTE_COUNT_SUBR(4);
12723         neo = tvb_get_letohl(tvb, offset);
12724         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12725         COUNT_BYTES_SUBR(4);
12726
12727         /* file index */
12728         CHECK_BYTE_COUNT_SUBR(4);
12729         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12730         COUNT_BYTES_SUBR(4);
12731
12732         /* create time */
12733         CHECK_BYTE_COUNT_SUBR(8);
12734         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12735         *bcp -= 8;
12736
12737         /* access time */
12738         CHECK_BYTE_COUNT_SUBR(8);
12739         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12740         *bcp -= 8;
12741
12742         /* last write time */
12743         CHECK_BYTE_COUNT_SUBR(8);
12744         offset = dissect_smb_64bit_time(tvb, tree, offset,
12745                 hf_smb_last_write_time);
12746         *bcp -= 8;
12747
12748         /* last change time */
12749         CHECK_BYTE_COUNT_SUBR(8);
12750         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12751         *bcp -= 8;
12752
12753         /* end of file */
12754         CHECK_BYTE_COUNT_SUBR(8);
12755         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12756         COUNT_BYTES_SUBR(8);
12757
12758         /* allocation size */
12759         CHECK_BYTE_COUNT_SUBR(8);
12760         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12761         COUNT_BYTES_SUBR(8);
12762
12763         /* Extended File Attributes */
12764         CHECK_BYTE_COUNT_SUBR(4);
12765         offset = dissect_file_ext_attr(tvb, tree, offset);
12766         *bcp -= 4;
12767
12768         /* file name len */
12769         CHECK_BYTE_COUNT_SUBR(4);
12770         fn_len = tvb_get_letohl(tvb, offset);
12771         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12772         COUNT_BYTES_SUBR(4);
12773
12774         /*
12775          * EA length.
12776          *
12777          * XXX - in one captures, this has the topmost bit set, and the
12778          * rest of the bits have the value 7.  Is the topmost bit being
12779          * set some indication that the value *isn't* the length of
12780          * the EAs?
12781          */
12782         CHECK_BYTE_COUNT_SUBR(4);
12783         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12784         COUNT_BYTES_SUBR(4);
12785
12786         /* short file name len */
12787         CHECK_BYTE_COUNT_SUBR(1);
12788         sfn_len = tvb_get_guint8(tvb, offset);
12789         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
12790         COUNT_BYTES_SUBR(1);
12791
12792         /* reserved byte */
12793         CHECK_BYTE_COUNT_SUBR(1);
12794         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12795         COUNT_BYTES_SUBR(1);
12796
12797         /* short file name */
12798         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
12799         CHECK_STRING_SUBR(sfn);
12800         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
12801                 sfn);
12802         COUNT_BYTES_SUBR(24);
12803
12804         /* file name */
12805         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12806         CHECK_STRING_SUBR(fn);
12807         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12808                 fn);
12809         COUNT_BYTES_SUBR(fn_len);
12810
12811         if (check_col(pinfo->cinfo, COL_INFO)) {
12812                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12813                 fn);
12814         }
12815
12816         /* skip to next structure */
12817         if(neo){
12818                 padcnt = (old_offset + neo) - offset;
12819                 if (padcnt < 0) {
12820                         /*
12821                          * XXX - this is bogus; flag it?
12822                          */
12823                         padcnt = 0;
12824                 }
12825                 if (padcnt != 0) {
12826                         CHECK_BYTE_COUNT_SUBR(padcnt);
12827                         COUNT_BYTES_SUBR(padcnt);
12828                 }
12829         }
12830
12831         proto_item_append_text(item, " File: %s", fn);
12832         proto_item_set_len(item, offset-old_offset);
12833
12834         *trunc = FALSE;
12835         return offset;
12836 }
12837
12838 static int
12839 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12840     int offset, guint16 *bcp, gboolean *trunc)
12841 {
12842         int fn_len;
12843         const char *fn;
12844         int old_offset = offset;
12845         proto_item *item = NULL;
12846         proto_tree *tree = NULL;
12847         smb_info_t *si;
12848         guint32 neo;
12849         int padcnt;
12850
12851         si = (smb_info_t *)pinfo->private_data;
12852
12853         if(parent_tree){
12854                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12855                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12856                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12857         }
12858
12859         /*
12860          * We assume that the presence of a next entry offset implies the
12861          * absence of a resume key, as appears to be the case for 4.3.4.6.
12862          */
12863
12864         /* next entry offset */
12865         CHECK_BYTE_COUNT_SUBR(4);
12866         neo = tvb_get_letohl(tvb, offset);
12867         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12868         COUNT_BYTES_SUBR(4);
12869
12870         /* file index */
12871         CHECK_BYTE_COUNT_SUBR(4);
12872         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12873         COUNT_BYTES_SUBR(4);
12874
12875         /* file name len */
12876         CHECK_BYTE_COUNT_SUBR(4);
12877         fn_len = tvb_get_letohl(tvb, offset);
12878         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12879         COUNT_BYTES_SUBR(4);
12880
12881         /* file name */
12882         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12883         CHECK_STRING_SUBR(fn);
12884         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12885                 fn);
12886         COUNT_BYTES_SUBR(fn_len);
12887
12888         if (check_col(pinfo->cinfo, COL_INFO)) {
12889                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12890                 fn);
12891         }
12892
12893         /* skip to next structure */
12894         if(neo){
12895                 padcnt = (old_offset + neo) - offset;
12896                 if (padcnt < 0) {
12897                         /*
12898                          * XXX - this is bogus; flag it?
12899                          */
12900                         padcnt = 0;
12901                 }
12902                 if (padcnt != 0) {
12903                         CHECK_BYTE_COUNT_SUBR(padcnt);
12904                         COUNT_BYTES_SUBR(padcnt);
12905                 }
12906         }
12907
12908         proto_item_append_text(item, " File: %s", fn);
12909         proto_item_set_len(item, offset-old_offset);
12910
12911         *trunc = FALSE;
12912         return offset;
12913 }
12914
12915 /* 4.3.4.8 - SMB_FIND_FILE_UNIX */
12916
12917 static int
12918 dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
12919                 proto_tree *tree, int offset, guint16 *bcp,
12920                 gboolean *trunc)
12921 {
12922         smb_info_t *si = pinfo->private_data;
12923         const char *fn;
12924         int fn_len;
12925
12926         /* NextEntryOffset */
12927         CHECK_BYTE_COUNT_SUBR(4);
12928         proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, TRUE);
12929         COUNT_BYTES_SUBR(4);
12930         
12931         /* ResumeKey */
12932         CHECK_BYTE_COUNT_SUBR(4);
12933         proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, TRUE);
12934         COUNT_BYTES_SUBR(4);
12935
12936         /* End of file (file size) */
12937         CHECK_BYTE_COUNT_SUBR(8);
12938         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
12939         COUNT_BYTES_SUBR(8);
12940
12941         /* Number of bytes */
12942         CHECK_BYTE_COUNT_SUBR(8);
12943         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
12944         COUNT_BYTES_SUBR(8);
12945
12946         /* Last status change */
12947         CHECK_BYTE_COUNT_SUBR(8);
12948         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
12949         *bcp -= 8;
12950
12951         /* Last access time */
12952         CHECK_BYTE_COUNT_SUBR(8);
12953         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
12954         *bcp -= 8;
12955
12956         /* Last modification time */
12957         CHECK_BYTE_COUNT_SUBR(8);
12958         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
12959         *bcp -= 8;
12960
12961         /* File owner uid */
12962         CHECK_BYTE_COUNT_SUBR(8);
12963         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
12964         COUNT_BYTES_SUBR(8);
12965
12966         /* File group gid */
12967         CHECK_BYTE_COUNT_SUBR(8);
12968         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
12969         COUNT_BYTES_SUBR(8);
12970
12971         /* File type */
12972         CHECK_BYTE_COUNT_SUBR(4);
12973         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
12974         COUNT_BYTES_SUBR(4);
12975
12976         /* Major device number */
12977         CHECK_BYTE_COUNT_SUBR(8);
12978         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
12979         COUNT_BYTES_SUBR(8);
12980
12981         /* Minor device number */
12982         CHECK_BYTE_COUNT_SUBR(8);
12983         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
12984         COUNT_BYTES_SUBR(8);
12985
12986         /* Unique id */
12987         CHECK_BYTE_COUNT_SUBR(8);
12988         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
12989         COUNT_BYTES_SUBR(8);
12990
12991         /* Permissions */
12992         CHECK_BYTE_COUNT_SUBR(8);
12993         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
12994         COUNT_BYTES_SUBR(8);
12995
12996         /* Nlinks */
12997         CHECK_BYTE_COUNT_SUBR(8);
12998         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
12999         COUNT_BYTES_SUBR(8);
13000
13001         /* Name */
13002
13003         fn = get_unicode_or_ascii_string(
13004                 tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
13005
13006         CHECK_STRING_SUBR(fn);
13007         proto_tree_add_string(
13008                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
13009         COUNT_BYTES_SUBR(fn_len);
13010
13011         /* Pad to 4 bytes */
13012
13013         if (offset % 4)
13014                 offset += 4 - (offset % 4);
13015
13016         *trunc = FALSE;
13017         return offset;
13018 }
13019
13020 /*dissect the data block for TRANS2_FIND_FIRST2*/
13021 static int
13022 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
13023     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
13024 {
13025         smb_info_t *si;
13026
13027         if(!*bcp){
13028                 return offset;
13029         }
13030
13031         si = (smb_info_t *)pinfo->private_data;
13032         switch(si->info_level){
13033         case 1:         /*Info Standard*/
13034                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
13035                     trunc);
13036                 break;
13037         case 2:         /*Info Query EA Size*/
13038                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13039                     trunc);
13040                 break;
13041         case 3:         /*Info Query EAs From List same as
13042                                 InfoQueryEASize*/
13043                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13044                     trunc);
13045                 break;
13046         case 0x0101:    /*Find File Directory Info*/
13047                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
13048                     trunc);
13049                 break;
13050         case 0x0102:    /*Find File Full Directory Info*/
13051                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
13052                     trunc);
13053                 break;
13054         case 0x0103:    /*Find File Names Info*/
13055                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
13056                     trunc);
13057                 break;
13058         case 0x0104:    /*Find File Both Directory Info*/
13059                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
13060                     trunc);
13061                 break;
13062         case 0x0202:    /*Find File UNIX*/
13063                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
13064                     trunc);
13065                 break;
13066         default:        /* unknown info level */
13067                 *trunc = FALSE;
13068                 break;
13069         }
13070         return offset;
13071 }
13072
13073
13074 static int
13075 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13076 {
13077         guint32 mask;
13078         proto_item *item = NULL;
13079         proto_tree *tree = NULL;
13080
13081         mask = tvb_get_letohl(tvb, offset);
13082
13083         if(parent_tree){
13084                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
13085                         "FS Attributes: 0x%08x", mask);
13086                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
13087         }
13088
13089         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
13090                 tvb, offset, 4, mask);
13091         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
13092                 tvb, offset, 4, mask);
13093         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
13094                 tvb, offset, 4, mask);
13095         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
13096                 tvb, offset, 4, mask);
13097         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
13098                 tvb, offset, 4, mask);
13099         proto_tree_add_boolean(tree, hf_smb_fs_attr_dim,
13100                 tvb, offset, 4, mask);
13101         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
13102                 tvb, offset, 4, mask);
13103
13104         offset += 4;
13105         return offset;
13106 }
13107
13108
13109 static int
13110 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13111 {
13112         guint32 mask;
13113         proto_item *item = NULL;
13114         proto_tree *tree = NULL;
13115
13116         mask = tvb_get_letohl(tvb, offset);
13117
13118         if(parent_tree){
13119                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
13120                         "Device Characteristics: 0x%08x", mask);
13121                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
13122         }
13123
13124         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
13125                 tvb, offset, 4, mask);
13126         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
13127                 tvb, offset, 4, mask);
13128         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
13129                 tvb, offset, 4, mask);
13130         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
13131                 tvb, offset, 4, mask);
13132         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
13133                 tvb, offset, 4, mask);
13134         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
13135                 tvb, offset, 4, mask);
13136         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
13137                 tvb, offset, 4, mask);
13138
13139         offset += 4;
13140         return offset;
13141 }
13142
13143 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
13144
13145 static const true_false_string tfs_smb_mac_access_ctrl = {
13146   "Macintosh Access Control Supported",
13147   "Macintosh Access Control Not Supported"
13148 };
13149
13150 static const true_false_string tfs_smb_mac_getset_comments = {
13151   "Macintosh Get & Set Comments Supported",
13152   "Macintosh Get & Set Comments Not Supported"
13153 };
13154
13155 static const true_false_string tfs_smb_mac_desktopdb_calls = {
13156   "Macintosh Get & Set Desktop Database Info Supported",
13157   "Macintosh Get & Set Desktop Database Info Supported"
13158 };
13159
13160 static const true_false_string tfs_smb_mac_unique_ids = {
13161   "Macintosh Unique IDs Supported",
13162   "Macintosh Unique IDs Not Supported"
13163 };
13164
13165 static const true_false_string tfs_smb_mac_streams = {
13166   "Macintosh and Streams Extensions Not Supported",
13167   "Macintosh and Streams Extensions Supported"
13168 };
13169
13170 static int
13171 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13172     int offset, guint16 *bcp)
13173 {
13174         smb_info_t *si;
13175         int fn_len, vll, fnl;
13176         const char *fn;
13177         guint support = 0;
13178         proto_item *item = NULL;
13179         proto_tree *ti = NULL;
13180
13181         if(!*bcp){
13182                 return offset;
13183         }
13184
13185         si = (smb_info_t *)pinfo->private_data;
13186         switch(si->info_level){
13187         case 1:         /* SMB_INFO_ALLOCATION */
13188                 /* filesystem id */
13189                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13190                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
13191                 COUNT_BYTES_TRANS_SUBR(4);
13192
13193                 /* sectors per unit */
13194                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13195                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13196                 COUNT_BYTES_TRANS_SUBR(4);
13197
13198                 /* units */
13199                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13200                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
13201                 COUNT_BYTES_TRANS_SUBR(4);
13202
13203                 /* avail units */
13204                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13205                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
13206                 COUNT_BYTES_TRANS_SUBR(4);
13207
13208                 /* bytes per sector, only 16bit integer here */
13209                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13210                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13211                 COUNT_BYTES_TRANS_SUBR(2);
13212
13213                 break;
13214         case 2:         /* SMB_INFO_VOLUME */
13215                 /* volume serial number */
13216                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13217                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
13218                 COUNT_BYTES_TRANS_SUBR(4);
13219
13220                 /* volume label length, only one byte here */
13221                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
13222                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
13223                 COUNT_BYTES_TRANS_SUBR(1);
13224
13225                 /* label */
13226                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
13227                 CHECK_STRING_TRANS_SUBR(fn);
13228                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13229                         fn);
13230                 COUNT_BYTES_TRANS_SUBR(fn_len);
13231
13232                 break;
13233         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
13234         case 1002:      /* SMB_FS_LABEL_INFORMATION */
13235                 /* volume label length */
13236                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13237                 vll = tvb_get_letohl(tvb, offset);
13238                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
13239                 COUNT_BYTES_TRANS_SUBR(4);
13240
13241                 /* label */
13242                 fn_len = vll;
13243                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13244                 CHECK_STRING_TRANS_SUBR(fn);
13245                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13246                         fn);
13247                 COUNT_BYTES_TRANS_SUBR(fn_len);
13248
13249                 break;
13250         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
13251         case 1001:      /* SMB_FS_VOLUME_INFORMATION */
13252                 /* create time */
13253                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13254                 offset = dissect_smb_64bit_time(tvb, tree, offset,
13255                         hf_smb_create_time);
13256                 *bcp -= 8;
13257
13258                 /* volume serial number */
13259                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13260                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
13261                 COUNT_BYTES_TRANS_SUBR(4);
13262
13263                 /* volume label length */
13264                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13265                 vll = tvb_get_letohl(tvb, offset);
13266                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
13267                 COUNT_BYTES_TRANS_SUBR(4);
13268
13269                 /* 2 reserved bytes */
13270                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13271                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
13272                 COUNT_BYTES_TRANS_SUBR(2);
13273
13274                 /* label */
13275                 fn_len = vll;
13276                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13277                 CHECK_STRING_TRANS_SUBR(fn);
13278                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13279                         fn);
13280                 COUNT_BYTES_TRANS_SUBR(fn_len);
13281
13282                 break;
13283         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
13284         case 1003:      /* SMB_FS_SIZE_INFORMATION */
13285                 /* allocation size */
13286                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13287                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13288                 COUNT_BYTES_TRANS_SUBR(8);
13289
13290                 /* free allocation units */
13291                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13292                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
13293                 COUNT_BYTES_TRANS_SUBR(8);
13294
13295                 /* sectors per unit */
13296                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13297                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13298                 COUNT_BYTES_TRANS_SUBR(4);
13299
13300                 /* bytes per sector */
13301                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13302                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
13303                 COUNT_BYTES_TRANS_SUBR(4);
13304
13305                 break;
13306         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
13307         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
13308                 /* device type */
13309                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13310                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
13311                 COUNT_BYTES_TRANS_SUBR(4);
13312
13313                 /* device characteristics */
13314                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13315                 offset = dissect_device_characteristics(tvb, tree, offset);
13316                 *bcp -= 4;
13317
13318                 break;
13319         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
13320         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
13321                 /* FS attributes */
13322                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13323                 offset = dissect_fs_attributes(tvb, tree, offset);
13324                 *bcp -= 4;
13325
13326                 /* max name len */
13327                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13328                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
13329                 COUNT_BYTES_TRANS_SUBR(4);
13330
13331                 /* fs name length */
13332                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13333                 fnl = tvb_get_letohl(tvb, offset);
13334                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
13335                 COUNT_BYTES_TRANS_SUBR(4);
13336
13337                 /* label */
13338                 fn_len = fnl;
13339                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13340                 CHECK_STRING_TRANS_SUBR(fn);
13341                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
13342                         fn);
13343                 COUNT_BYTES_TRANS_SUBR(fn_len);
13344
13345                 break;
13346         case 0x200: {   /* SMB_QUERY_CIFS_UNIX_INFO */
13347                 proto_item *item = NULL;
13348                 proto_tree *subtree = NULL;
13349                 guint32 caps_lo, caps_hi;
13350
13351                 /* MajorVersionNumber */
13352                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13353                 proto_tree_add_item(tree, hf_smb_unix_major_version, tvb, offset, 2, TRUE);
13354                 COUNT_BYTES_TRANS_SUBR(2);
13355
13356                 /* MinorVersionNumber */
13357                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13358                 proto_tree_add_item(tree, hf_smb_unix_minor_version, tvb, offset, 2, TRUE);
13359                 COUNT_BYTES_TRANS_SUBR(2);
13360
13361                 /* Capability */
13362
13363                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13364
13365                 caps_lo = tvb_get_letohl(tvb, offset);
13366                 caps_hi = tvb_get_letohl(tvb, offset + 4);
13367
13368                 if (tree) {
13369                         item = proto_tree_add_text(
13370                                 tree, tvb, offset, 8, "Capabilities: 0x%08x%08x", 
13371                                 caps_hi, caps_lo);
13372                         subtree = proto_item_add_subtree(
13373                                 item, ett_smb_unix_capabilities);
13374                 }
13375
13376                 proto_tree_add_boolean(
13377                         subtree, hf_smb_unix_capability_fcntl, tvb, offset, 8, 
13378                         caps_lo);
13379
13380                 proto_tree_add_boolean(
13381                         subtree, hf_smb_unix_capability_posix_acl, tvb, offset, 8, 
13382                         caps_lo);
13383
13384                 COUNT_BYTES_TRANS_SUBR(8);
13385
13386                 break;
13387         }
13388         case 0x301:     /* MAC_QUERY_FS_INFO */
13389                 /* Create time */
13390                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13391                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
13392                 *bcp -= 8;
13393                 /* Modify Time */
13394                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13395                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_modify_time);
13396                 *bcp -= 8;
13397                 /* Backup Time */
13398                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13399                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_backup_time);
13400                 *bcp -= 8;
13401                 /* Allocation blocks */
13402                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13403                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
13404                                     offset,
13405                                     4, TRUE);
13406                 COUNT_BYTES_TRANS_SUBR(4);
13407                 /* Allocation Block Size */
13408                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13409                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
13410                                     offset, 4, TRUE);
13411                 COUNT_BYTES_TRANS_SUBR(4);
13412                 /* Free Block Count */
13413                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13414                 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
13415                                     offset, 4, TRUE);
13416                 COUNT_BYTES_TRANS_SUBR(4);
13417                 /* Finder Info ... */
13418                 CHECK_BYTE_COUNT_TRANS_SUBR(32);
13419                 proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb,
13420                                             offset, 32,
13421                                             tvb_get_ptr(tvb, offset,32),
13422                                             "Finder Info: %s",
13423                                             tvb_format_text(tvb, offset, 32));
13424                 COUNT_BYTES_TRANS_SUBR(32);
13425                 /* Number Files */
13426                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13427                 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
13428                                     offset, 4, TRUE);
13429                 COUNT_BYTES_TRANS_SUBR(4);
13430                 /* Number of Root Directories */
13431                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13432                 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
13433                                     offset, 4, TRUE);
13434                 COUNT_BYTES_TRANS_SUBR(4);
13435                 /* Number of files */
13436                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13437                 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
13438                                     offset, 4, TRUE);
13439                 COUNT_BYTES_TRANS_SUBR(4);
13440                 /* Dir Count */
13441                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13442                 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
13443                                     offset, 4, TRUE);
13444                 COUNT_BYTES_TRANS_SUBR(4);
13445                 /* Mac Support Flags */
13446                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13447                 support = tvb_get_ntohl(tvb, offset);
13448                 item = proto_tree_add_text(tree, tvb, offset, 4,
13449                                            "Mac Support Flags: 0x%08x", support);
13450                 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
13451                 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
13452                                        tvb, offset, 4, support);
13453                 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
13454                                        tvb, offset, 4, support);
13455                 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
13456                                        tvb, offset, 4, support);
13457                 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
13458                                        tvb, offset, 4, support);
13459                 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
13460                                        tvb, offset, 4, support);
13461                 COUNT_BYTES_TRANS_SUBR(4);
13462                 break;
13463         case 1006:      /* QUERY_FS_QUOTA_INFO */
13464                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
13465                 break;
13466         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
13467                 /* allocation size */
13468                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13469                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13470                 COUNT_BYTES_TRANS_SUBR(8);
13471
13472                 /* caller free allocation units */
13473                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13474                 proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
13475                 COUNT_BYTES_TRANS_SUBR(8);
13476
13477                 /* actual free allocation units */
13478                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13479                 proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
13480                 COUNT_BYTES_TRANS_SUBR(8);
13481
13482                 /* sectors per unit */
13483                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13484                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13485                 COUNT_BYTES_TRANS_SUBR(4);
13486
13487                 /* bytes per sector */
13488                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13489                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
13490                 COUNT_BYTES_TRANS_SUBR(4);
13491                 break;
13492         case 1008: /* Query Object ID is GUID plus unknown data */ {
13493                 e_uuid_t fs_id;
13494                 char uuid_str[DCERPC_UUID_STR_LEN]; 
13495                 int uuid_str_len;
13496                 char drep = 0x10;
13497                 
13498                 CHECK_BYTE_COUNT_TRANS_SUBR(16);
13499
13500                 dcerpc_tvb_get_uuid (tvb, offset, &drep, &fs_id);
13501
13502                 uuid_str_len = snprintf(
13503                         uuid_str, DCERPC_UUID_STR_LEN, 
13504                         "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
13505                         fs_id.Data1, fs_id.Data2, fs_id.Data3,
13506                         fs_id.Data4[0], fs_id.Data4[1],
13507                         fs_id.Data4[2], fs_id.Data4[3],
13508                         fs_id.Data4[4], fs_id.Data4[5],
13509                         fs_id.Data4[6], fs_id.Data4[7]);
13510
13511                 proto_tree_add_string_format(
13512                         tree, hf_smb_fs_guid, tvb,
13513                         offset, 16, uuid_str, "GUID: %s", uuid_str);
13514
13515                 COUNT_BYTES_TRANS_SUBR(16);
13516                 break;
13517             }
13518         }
13519
13520         return offset;
13521 }
13522
13523 static int
13524 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
13525     proto_tree *parent_tree)
13526 {
13527         proto_item *item = NULL;
13528         proto_tree *tree = NULL;
13529         smb_info_t *si;
13530         smb_transact2_info_t *t2i;
13531         int count;
13532         gboolean trunc;
13533         int offset = 0;
13534         guint16 dc;
13535
13536         dc = tvb_reported_length(tvb);
13537
13538         si = (smb_info_t *)pinfo->private_data;
13539         if (si->sip != NULL)
13540                 t2i = si->sip->extra_info;
13541         else
13542                 t2i = NULL;
13543
13544         if(parent_tree){
13545                 if (t2i != NULL && t2i->subcmd != -1) {
13546                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13547                                 "%s Data",
13548                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
13549                                         "Unknown (0x%02x)"));
13550                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
13551                 } else {
13552                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13553                                 "Unknown Transaction2 Data");
13554                 }
13555         }
13556
13557         if (t2i == NULL) {
13558                 offset += dc;
13559                 return offset;
13560         }
13561         switch(t2i->subcmd){
13562         case 0x00:      /*TRANS2_OPEN2*/
13563                 /* XXX not implemented yet. See SNIA doc */
13564                 break;
13565         case 0x01:      /*TRANS2_FIND_FIRST2*/
13566                 /* returned data */
13567                 count = si->info_count;
13568
13569                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
13570                         col_append_fstr(pinfo->cinfo, COL_INFO,
13571                         ", Files:");
13572                 }
13573
13574                 while(count--){
13575                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
13576                                 offset, &dc, &trunc);
13577                         if (trunc)
13578                                 break;
13579                 }
13580                 break;
13581         case 0x02:      /*TRANS2_FIND_NEXT2*/
13582                 /* returned data */
13583                 count = si->info_count;
13584
13585                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
13586                         col_append_fstr(pinfo->cinfo, COL_INFO,
13587                         ", Files:");
13588                 }
13589
13590                 while(count--){
13591                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
13592                                 offset, &dc, &trunc);
13593                         if (trunc)
13594                                 break;
13595                 }
13596                 break;
13597         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
13598                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
13599                 break;
13600         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
13601                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
13602                 break;
13603         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
13604                 /* no data in this response */
13605                 break;
13606         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
13607                 /* identical to QUERY_PATH_INFO */
13608                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
13609                 break;
13610         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
13611                 /* no data in this response */
13612                 break;
13613         case 0x09:      /*TRANS2_FSCTL*/
13614                 /* XXX dont know how to dissect this one (yet)*/
13615
13616                 /*
13617                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13618                  * Extensions Version 3.0, Document Version 1.11,
13619                  * July 19, 1990" says this this contains a
13620                  * "File system specific return data block".
13621                  * (That means we may not be able to dissect it in any
13622                  * case.)
13623                  */
13624                 break;
13625         case 0x0a:      /*TRANS2_IOCTL2*/
13626                 /* XXX dont know how to dissect this one (yet)*/
13627
13628                 /*
13629                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13630                  * Extensions Version 3.0, Document Version 1.11,
13631                  * July 19, 1990" says this this contains a
13632                  * "Device/function specific return data block".
13633                  * (That means we may not be able to dissect it in any
13634                  * case.)
13635                  */
13636                 break;
13637         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
13638                 /* XXX dont know how to dissect this one (yet)*/
13639
13640                 /*
13641                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13642                  * Extensions Version 3.0, Document Version 1.11,
13643                  * July 19, 1990" says this this contains "the level
13644                  * dependent information about the changes which
13645                  * occurred".
13646                  */
13647                 break;
13648         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
13649                 /* XXX dont know how to dissect this one (yet)*/
13650
13651                 /*
13652                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13653                  * Extensions Version 3.0, Document Version 1.11,
13654                  * July 19, 1990" says this this contains "the level
13655                  * dependent information about the changes which
13656                  * occurred".
13657                  */
13658                 break;
13659         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
13660                 /* no data in this response */
13661                 break;
13662         case 0x0e:      /*TRANS2_SESSION_SETUP*/
13663                 /* XXX dont know how to dissect this one (yet)*/
13664                 break;
13665         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
13666                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
13667                 break;
13668         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13669                 /* the SNIA spec appears to say the response has no data */
13670                 break;
13671         case -1:
13672                 /*
13673                  * We don't know what the matching request was; don't
13674                  * bother putting anything else into the tree for the data.
13675                  */
13676                 offset += dc;
13677                 dc = 0;
13678                 break;
13679         }
13680
13681         /* ooops there were data we didnt know how to process */
13682         if(dc != 0){
13683                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
13684                 offset += dc;
13685         }
13686
13687         return offset;
13688 }
13689
13690
13691 static void
13692 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
13693 {
13694         proto_item *item = NULL;
13695         proto_tree *tree = NULL;
13696         smb_info_t *si;
13697         smb_transact2_info_t *t2i;
13698         guint16 fid;
13699         int lno;
13700         int offset = 0;
13701         int pc;
13702
13703         pc = tvb_reported_length(tvb);
13704
13705         si = (smb_info_t *)pinfo->private_data;
13706         if (si->sip != NULL)
13707                 t2i = si->sip->extra_info;
13708         else
13709                 t2i = NULL;
13710
13711         if(parent_tree){
13712                 if (t2i != NULL && t2i->subcmd != -1) {
13713                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13714                                 "%s Parameters",
13715                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
13716                                                 "Unknown (0x%02x)"));
13717                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
13718                 } else {
13719                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13720                                 "Unknown Transaction2 Parameters");
13721                 }
13722         }
13723
13724         if (t2i == NULL) {
13725                 offset += pc;
13726                 return;
13727         }
13728         switch(t2i->subcmd){
13729         case 0x00:      /*TRANS2_OPEN2*/
13730                 /* fid */
13731                 fid = tvb_get_letohs(tvb, offset);
13732                 add_fid(tvb, pinfo, tree, offset, 2, fid);
13733                 offset += 2;
13734
13735                 /*
13736                  * XXX - Microsoft Networks SMB File Sharing Protocol
13737                  * Extensions Version 3.0, Document Version 1.11,
13738                  * July 19, 1990 says that the file attributes, create
13739                  * time (which it says is the last modification time),
13740                  * data size, granted access, file type, and IPC state
13741                  * are returned only if bit 0 is set in the open flags,
13742                  * and that the EA length is returned only if bit 3
13743                  * is set in the open flags.  Does that mean that,
13744                  * at least in that SMB dialect, those fields are not
13745                  * present in the reply parameters if the bits in
13746                  * question aren't set?
13747                  */
13748
13749                 /* File Attributes */
13750                 offset = dissect_file_attributes(tvb, tree, offset, 2);
13751
13752                 /* create time */
13753                 offset = dissect_smb_datetime(tvb, tree, offset,
13754                         hf_smb_create_time,
13755                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
13756
13757                 /* data size */
13758                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
13759                 offset += 4;
13760
13761                 /* granted access */
13762                 offset = dissect_access(tvb, tree, offset, "Granted");
13763
13764                 /* File Type */
13765                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
13766                 offset += 2;
13767
13768                 /* IPC State */
13769                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
13770
13771                 /* open_action */
13772                 offset = dissect_open_action(tvb, tree, offset);
13773
13774                 /* server unique file ID */
13775                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
13776                 offset += 4;
13777
13778                 /* ea error offset, only a 16 bit integer here */
13779                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13780                 offset += 2;
13781
13782                 /* ea length */
13783                 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13784                 offset += 4;
13785
13786                 break;
13787         case 0x01:      /*TRANS2_FIND_FIRST2*/
13788                 /* Find First2 information level */
13789                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
13790
13791                 /* sid */
13792                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
13793                 offset += 2;
13794
13795                 /* search count */
13796                 si->info_count = tvb_get_letohs(tvb, offset);
13797                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13798                 offset += 2;
13799
13800                 /* end of search */
13801                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13802                 offset += 2;
13803
13804                 /* ea error offset, only a 16 bit integer here */
13805                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13806                 offset += 2;
13807
13808                 /* last name offset */
13809                 lno = tvb_get_letohs(tvb, offset);
13810                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13811                 offset += 2;
13812
13813                 break;
13814         case 0x02:      /*TRANS2_FIND_NEXT2*/
13815                 /* search count */
13816                 si->info_count = tvb_get_letohs(tvb, offset);
13817                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13818                 offset += 2;
13819
13820                 /* end of search */
13821                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13822                 offset += 2;
13823
13824                 /* ea_error_offset, only a 16 bit integer here*/
13825                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13826                 offset += 2;
13827
13828                 /* last name offset */
13829                 lno = tvb_get_letohs(tvb, offset);
13830                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13831                 offset += 2;
13832
13833                 break;
13834         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
13835                 /* no parameter block here */
13836                 break;
13837         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
13838                 /* ea_error_offset, only a 16 bit integer here*/
13839                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13840                 offset += 2;
13841
13842                 break;
13843         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
13844                 /* ea_error_offset, only a 16 bit integer here*/
13845                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13846                 offset += 2;
13847
13848                 break;
13849         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
13850                 /* ea_error_offset, only a 16 bit integer here*/
13851                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13852                 offset += 2;
13853
13854                 break;
13855         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
13856                 /* ea_error_offset, only a 16 bit integer here*/
13857                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13858                 offset += 2;
13859
13860                 break;
13861         case 0x09:      /*TRANS2_FSCTL*/
13862                 /* XXX dont know how to dissect this one (yet)*/
13863
13864                 /*
13865                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13866                  * Extensions Version 3.0, Document Version 1.11,
13867                  * July 19, 1990" says this this contains a
13868                  * "File system specific return parameter block".
13869                  * (That means we may not be able to dissect it in any
13870                  * case.)
13871                  */
13872                 break;
13873         case 0x0a:      /*TRANS2_IOCTL2*/
13874                 /* XXX dont know how to dissect this one (yet)*/
13875
13876                 /*
13877                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13878                  * Extensions Version 3.0, Document Version 1.11,
13879                  * July 19, 1990" says this this contains a
13880                  * "Device/function specific return parameter block".
13881                  * (That means we may not be able to dissect it in any
13882                  * case.)
13883                  */
13884                 break;
13885         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
13886                 /* Find Notify information level */
13887                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13888
13889                 /* Monitor handle */
13890                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
13891                 offset += 2;
13892
13893                 /* Change count */
13894                 si->info_count = tvb_get_letohs(tvb, offset);
13895                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13896                 offset += 2;
13897
13898                 /* ea_error_offset, only a 16 bit integer here*/
13899                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13900                 offset += 2;
13901
13902                 break;
13903         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
13904                 /* Find Notify information level */
13905                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13906
13907                 /* Change count */
13908                 si->info_count = tvb_get_letohs(tvb, offset);
13909                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13910                 offset += 2;
13911
13912                 /* ea_error_offset, only a 16 bit integer here*/
13913                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13914                 offset += 2;
13915
13916                 break;
13917         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
13918                 /* ea error offset, only a 16 bit integer here */
13919                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13920                 offset += 2;
13921
13922                 break;
13923         case 0x0e:      /*TRANS2_SESSION_SETUP*/
13924                 /* XXX dont know how to dissect this one (yet)*/
13925                 break;
13926         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
13927                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
13928                 break;
13929         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13930                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
13931                 break;
13932         case -1:
13933                 /*
13934                  * We don't know what the matching request was; don't
13935                  * bother putting anything else into the tree for the data.
13936                  */
13937                 offset += pc;
13938                 break;
13939         }
13940
13941         /* ooops there were data we didnt know how to process */
13942         if(offset<pc){
13943                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
13944                 offset += pc-offset;
13945         }
13946 }
13947
13948
13949 static int
13950 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13951 {
13952         guint8 sc, wc;
13953         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
13954         smb_info_t *si;
13955         smb_transact2_info_t *t2i = NULL;
13956         guint16 bc;
13957         int padcnt;
13958         gboolean dissected_trans;
13959         fragment_data *r_fd = NULL;
13960         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
13961         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
13962         gboolean save_fragmented;
13963
13964         si = (smb_info_t *)pinfo->private_data;
13965
13966         switch(si->cmd){
13967         case SMB_COM_TRANSACTION2:
13968                 /* transaction2 */
13969                 if (si->sip != NULL) {
13970                         t2i = si->sip->extra_info;
13971                 } else
13972                         t2i = NULL;
13973                 if (t2i == NULL) {
13974                         /*
13975                          * We didn't see the matching request, so we don't
13976                          * know what type of transaction this is.
13977                          */
13978                         proto_tree_add_text(tree, tvb, 0, 0,
13979                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
13980                         if (check_col(pinfo->cinfo, COL_INFO)) {
13981                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
13982                         }
13983                 } else {
13984                         si->info_level = t2i->info_level;
13985                         if (t2i->subcmd == -1) {
13986                                 /*
13987                                  * We didn't manage to extract the subcommand
13988                                  * from the matching request (perhaps because
13989                                  * the frame was short), so we don't know what
13990                                  * type of transaction this is.
13991                                  */
13992                                 proto_tree_add_text(tree, tvb, 0, 0,
13993                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
13994                                 if (check_col(pinfo->cinfo, COL_INFO)) {
13995                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
13996                                 }
13997                         } else {
13998                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
13999                                 if (check_col(pinfo->cinfo, COL_INFO)) {
14000                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
14001                                                 val_to_str(t2i->subcmd,
14002                                                         trans2_cmd_vals,
14003                                                         "<unknown (0x%02x)>"));
14004                                 }
14005                         }
14006                 }
14007                 break;
14008         }
14009
14010         WORD_COUNT;
14011
14012         /* total param count, only a 16bit integer here */
14013         tp = tvb_get_letohs(tvb, offset);
14014         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
14015         offset += 2;
14016
14017         /* total data count, only a 16 bit integer here */
14018         td = tvb_get_letohs(tvb, offset);
14019         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
14020         offset += 2;
14021
14022         /* 2 reserved bytes */
14023         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
14024         offset += 2;
14025
14026         /* param count */
14027         pc = tvb_get_letohs(tvb, offset);
14028         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
14029         offset += 2;
14030
14031         /* param offset */
14032         po = tvb_get_letohs(tvb, offset);
14033         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
14034         offset += 2;
14035
14036         /* param disp */
14037         pd = tvb_get_letohs(tvb, offset);
14038         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
14039         offset += 2;
14040
14041         /* data count */
14042         dc = tvb_get_letohs(tvb, offset);
14043         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
14044         offset += 2;
14045
14046         /* data offset */
14047         od = tvb_get_letohs(tvb, offset);
14048         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
14049         offset += 2;
14050
14051         /* data disp */
14052         dd = tvb_get_letohs(tvb, offset);
14053         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
14054         offset += 2;
14055
14056         /* setup count */
14057         sc = tvb_get_guint8(tvb, offset);
14058         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
14059         offset += 1;
14060
14061         /* reserved byte */
14062         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
14063         offset += 1;
14064
14065
14066         /* if there were any setup bytes, put them in a tvb for later */
14067         if(sc){
14068                 if((2*sc)>tvb_length_remaining(tvb, offset)){
14069                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
14070                 } else {
14071                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
14072                 }
14073                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
14074         } else {
14075                 s_tvb = NULL;
14076                 sp_tvb=NULL;
14077         }
14078         offset += 2*sc;
14079
14080
14081         BYTE_COUNT;
14082
14083
14084         /* reassembly of SMB Transaction data payload.
14085            In this section we do reassembly of both the data and parameters
14086            blocks of the SMB transaction command.
14087         */
14088         save_fragmented = pinfo->fragmented;
14089         /* do we need reassembly? */
14090         if( (td!=dc) || (tp!=pc) ){
14091                 /* oh yeah, either data or parameter section needs
14092                    reassembly
14093                 */
14094                 pinfo->fragmented = TRUE;
14095                 if(smb_trans_reassembly){
14096                         /* ...and we were told to do reassembly */
14097                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
14098                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
14099                                                              po, pc, pd, td+tp);
14100
14101                         }
14102                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
14103                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
14104                                                              od, dc, dd+tp, td+tp);
14105                         }
14106                 }
14107         }
14108
14109         /* if we got a reassembled fd structure from the reassembly routine we must
14110            create pd_tvb from it
14111         */
14112         if(r_fd){
14113                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
14114                                              r_fd->datalen);
14115                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
14116                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
14117                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
14118         }
14119
14120
14121         if(pd_tvb){
14122                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
14123                 if(tp){
14124                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
14125                 }
14126                 if(td){
14127                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
14128                 }
14129         } else {
14130                 /* It was not reassembled. Do as best as we can.
14131                  * in this case we always try to dissect the stuff if
14132                  * data and param displacement is 0. i.e. for the first
14133                  * (and maybe only) packet.
14134                  */
14135                 if( (pd==0) && (dd==0) ){
14136                         int min;
14137                         int reported_min;
14138                         min = MIN(pc,tvb_length_remaining(tvb,po));
14139                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
14140                         if(min && reported_min) {
14141                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
14142                         }
14143                         min = MIN(dc,tvb_length_remaining(tvb,od));
14144                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
14145                         if(min && reported_min) {
14146                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
14147                         }
14148                         /*
14149                          * A tvbuff containing the parameters
14150                          * and the data.
14151                          * XXX - check pc and dc as well?
14152                          */
14153                         if (tvb_length_remaining(tvb, po)){
14154                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
14155                         }
14156                 }
14157         }
14158
14159
14160
14161         /* parameters */
14162         if(po>offset){
14163                 /* We have some padding bytes.
14164                 */
14165                 padcnt = po-offset;
14166                 if (padcnt > bc)
14167                         padcnt = bc;
14168                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
14169                 COUNT_BYTES(padcnt);
14170         }
14171         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
14172                 /* TRANSACTION2 parameters*/
14173                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
14174         }
14175         COUNT_BYTES(pc);
14176
14177
14178         /* data */
14179         if(od>offset){
14180                 /* We have some initial padding bytes.
14181                 */
14182                 padcnt = od-offset;
14183                 if (padcnt > bc)
14184                         padcnt = bc;
14185                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
14186                 COUNT_BYTES(padcnt);
14187         }
14188         /*
14189          * If the data count is bigger than the count of bytes
14190          * remaining, clamp it so that the count of bytes remaining
14191          * doesn't go negative.
14192          */
14193         if (dc > bc)
14194                 dc = bc;
14195         COUNT_BYTES(dc);
14196
14197
14198
14199         /* from now on, everything is in separate tvbuffs so we dont count
14200            the bytes with COUNT_BYTES any more.
14201            neither do we reference offset any more (which by now points to the
14202            first byte AFTER this PDU */
14203
14204
14205         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
14206                 /* TRANSACTION2 parameters*/
14207                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
14208         }
14209
14210
14211         if(si->cmd==SMB_COM_TRANSACTION){
14212                 smb_transact_info_t *tri;
14213
14214                 dissected_trans = FALSE;
14215                 if (si->sip != NULL)
14216                         tri = si->sip->extra_info;
14217                 else
14218                         tri = NULL;
14219                 if (tri != NULL) {
14220                         switch(tri->subcmd){
14221
14222                         case TRANSACTION_PIPE:
14223                                 /* This function is safe to call for
14224                                    s_tvb==sp_tvb==NULL, i.e. if we don't
14225                                    know them at this point.
14226                                    It's also safe to call if "p_tvb"
14227                                    or "d_tvb" are null.
14228                                 */
14229                                 if( pd_tvb) {
14230                                         dissected_trans = dissect_pipe_smb(
14231                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
14232                                                 d_tvb, NULL, pinfo, top_tree);
14233                                 }
14234                                 break;
14235
14236                         case TRANSACTION_MAILSLOT:
14237                                 /* This one should be safe to call
14238                                    even if s_tvb and sp_tvb is NULL
14239                                 */
14240                                 if(d_tvb){
14241                                         dissected_trans = dissect_mailslot_smb(
14242                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
14243                                                 top_tree);
14244                                 }
14245                                 break;
14246                         }
14247                 }
14248                 if (!dissected_trans) {
14249                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
14250                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
14251                 }
14252         }
14253
14254
14255         if( (p_tvb==0) && (d_tvb==0) ){
14256                 if(check_col(pinfo->cinfo, COL_INFO)){
14257                         col_append_str(pinfo->cinfo, COL_INFO,
14258                                        "[transact continuation]");
14259                 }
14260         }
14261
14262         pinfo->fragmented = save_fragmented;
14263         END_OF_SMB
14264
14265         return offset;
14266 }
14267
14268
14269 static int
14270 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14271 {
14272         guint8 wc;
14273         guint16 bc;
14274
14275         WORD_COUNT;
14276
14277         /* Monitor handle */
14278         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
14279         offset += 2;
14280
14281         BYTE_COUNT;
14282
14283         END_OF_SMB
14284
14285         return offset;
14286 }
14287
14288 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14289    END Transaction/Transaction2 Primary and secondary requests
14290    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
14291
14292
14293 static int
14294 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14295 {
14296         guint8 wc;
14297         guint16 bc;
14298
14299         WORD_COUNT;
14300
14301         if (wc != 0) {
14302                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
14303                 offset += wc*2;
14304         }
14305
14306         BYTE_COUNT;
14307
14308         if (bc != 0) {
14309                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
14310                 offset += bc;
14311                 bc = 0;
14312         }
14313
14314         END_OF_SMB
14315
14316         return offset;
14317 }
14318
14319 typedef struct _smb_function {
14320        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14321        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14322 } smb_function;
14323
14324 static smb_function smb_dissector[256] = {
14325   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
14326   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
14327   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
14328   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
14329   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
14330   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
14331   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
14332   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
14333   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
14334   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
14335   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
14336   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
14337   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
14338   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
14339   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
14340   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
14341
14342   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
14343   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
14344   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
14345   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
14346   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
14347   /* 0x15 */  {dissect_unknown, dissect_unknown},
14348   /* 0x16 */  {dissect_unknown, dissect_unknown},
14349   /* 0x17 */  {dissect_unknown, dissect_unknown},
14350   /* 0x18 */  {dissect_unknown, dissect_unknown},
14351   /* 0x19 */  {dissect_unknown, dissect_unknown},
14352   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
14353   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
14354   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
14355   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
14356   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
14357   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
14358
14359   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
14360   /* 0x21 */  {dissect_unknown, dissect_unknown},
14361   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
14362   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
14363   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
14364   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
14365   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
14366   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
14367   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
14368   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
14369   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
14370   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
14371   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
14372   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
14373   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
14374   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
14375
14376   /* 0x30 */  {dissect_unknown, dissect_unknown},
14377   /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
14378   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
14379   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
14380   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
14381   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
14382   /* 0x36 */  {dissect_unknown, dissect_unknown},
14383   /* 0x37 */  {dissect_unknown, dissect_unknown},
14384   /* 0x38 */  {dissect_unknown, dissect_unknown},
14385   /* 0x39 */  {dissect_unknown, dissect_unknown},
14386   /* 0x3a */  {dissect_unknown, dissect_unknown},
14387   /* 0x3b */  {dissect_unknown, dissect_unknown},
14388   /* 0x3c */  {dissect_unknown, dissect_unknown},
14389   /* 0x3d */  {dissect_unknown, dissect_unknown},
14390   /* 0x3e */  {dissect_unknown, dissect_unknown},
14391   /* 0x3f */  {dissect_unknown, dissect_unknown},
14392
14393   /* 0x40 */  {dissect_unknown, dissect_unknown},
14394   /* 0x41 */  {dissect_unknown, dissect_unknown},
14395   /* 0x42 */  {dissect_unknown, dissect_unknown},
14396   /* 0x43 */  {dissect_unknown, dissect_unknown},
14397   /* 0x44 */  {dissect_unknown, dissect_unknown},
14398   /* 0x45 */  {dissect_unknown, dissect_unknown},
14399   /* 0x46 */  {dissect_unknown, dissect_unknown},
14400   /* 0x47 */  {dissect_unknown, dissect_unknown},
14401   /* 0x48 */  {dissect_unknown, dissect_unknown},
14402   /* 0x49 */  {dissect_unknown, dissect_unknown},
14403   /* 0x4a */  {dissect_unknown, dissect_unknown},
14404   /* 0x4b */  {dissect_unknown, dissect_unknown},
14405   /* 0x4c */  {dissect_unknown, dissect_unknown},
14406   /* 0x4d */  {dissect_unknown, dissect_unknown},
14407   /* 0x4e */  {dissect_unknown, dissect_unknown},
14408   /* 0x4f */  {dissect_unknown, dissect_unknown},
14409
14410   /* 0x50 */  {dissect_unknown, dissect_unknown},
14411   /* 0x51 */  {dissect_unknown, dissect_unknown},
14412   /* 0x52 */  {dissect_unknown, dissect_unknown},
14413   /* 0x53 */  {dissect_unknown, dissect_unknown},
14414   /* 0x54 */  {dissect_unknown, dissect_unknown},
14415   /* 0x55 */  {dissect_unknown, dissect_unknown},
14416   /* 0x56 */  {dissect_unknown, dissect_unknown},
14417   /* 0x57 */  {dissect_unknown, dissect_unknown},
14418   /* 0x58 */  {dissect_unknown, dissect_unknown},
14419   /* 0x59 */  {dissect_unknown, dissect_unknown},
14420   /* 0x5a */  {dissect_unknown, dissect_unknown},
14421   /* 0x5b */  {dissect_unknown, dissect_unknown},
14422   /* 0x5c */  {dissect_unknown, dissect_unknown},
14423   /* 0x5d */  {dissect_unknown, dissect_unknown},
14424   /* 0x5e */  {dissect_unknown, dissect_unknown},
14425   /* 0x5f */  {dissect_unknown, dissect_unknown},
14426
14427   /* 0x60 */  {dissect_unknown, dissect_unknown},
14428   /* 0x61 */  {dissect_unknown, dissect_unknown},
14429   /* 0x62 */  {dissect_unknown, dissect_unknown},
14430   /* 0x63 */  {dissect_unknown, dissect_unknown},
14431   /* 0x64 */  {dissect_unknown, dissect_unknown},
14432   /* 0x65 */  {dissect_unknown, dissect_unknown},
14433   /* 0x66 */  {dissect_unknown, dissect_unknown},
14434   /* 0x67 */  {dissect_unknown, dissect_unknown},
14435   /* 0x68 */  {dissect_unknown, dissect_unknown},
14436   /* 0x69 */  {dissect_unknown, dissect_unknown},
14437   /* 0x6a */  {dissect_unknown, dissect_unknown},
14438   /* 0x6b */  {dissect_unknown, dissect_unknown},
14439   /* 0x6c */  {dissect_unknown, dissect_unknown},
14440   /* 0x6d */  {dissect_unknown, dissect_unknown},
14441   /* 0x6e */  {dissect_unknown, dissect_unknown},
14442   /* 0x6f */  {dissect_unknown, dissect_unknown},
14443
14444   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
14445   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
14446   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
14447   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
14448   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
14449   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
14450   /* 0x76 */  {dissect_unknown, dissect_unknown},
14451   /* 0x77 */  {dissect_unknown, dissect_unknown},
14452   /* 0x78 */  {dissect_unknown, dissect_unknown},
14453   /* 0x79 */  {dissect_unknown, dissect_unknown},
14454   /* 0x7a */  {dissect_unknown, dissect_unknown},
14455   /* 0x7b */  {dissect_unknown, dissect_unknown},
14456   /* 0x7c */  {dissect_unknown, dissect_unknown},
14457   /* 0x7d */  {dissect_unknown, dissect_unknown},
14458   /* 0x7e */  {dissect_unknown, dissect_unknown},
14459   /* 0x7f */  {dissect_unknown, dissect_unknown},
14460
14461   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
14462   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
14463   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
14464   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
14465   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
14466   /* 0x85 */  {dissect_unknown, dissect_unknown},
14467   /* 0x86 */  {dissect_unknown, dissect_unknown},
14468   /* 0x87 */  {dissect_unknown, dissect_unknown},
14469   /* 0x88 */  {dissect_unknown, dissect_unknown},
14470   /* 0x89 */  {dissect_unknown, dissect_unknown},
14471   /* 0x8a */  {dissect_unknown, dissect_unknown},
14472   /* 0x8b */  {dissect_unknown, dissect_unknown},
14473   /* 0x8c */  {dissect_unknown, dissect_unknown},
14474   /* 0x8d */  {dissect_unknown, dissect_unknown},
14475   /* 0x8e */  {dissect_unknown, dissect_unknown},
14476   /* 0x8f */  {dissect_unknown, dissect_unknown},
14477
14478   /* 0x90 */  {dissect_unknown, dissect_unknown},
14479   /* 0x91 */  {dissect_unknown, dissect_unknown},
14480   /* 0x92 */  {dissect_unknown, dissect_unknown},
14481   /* 0x93 */  {dissect_unknown, dissect_unknown},
14482   /* 0x94 */  {dissect_unknown, dissect_unknown},
14483   /* 0x95 */  {dissect_unknown, dissect_unknown},
14484   /* 0x96 */  {dissect_unknown, dissect_unknown},
14485   /* 0x97 */  {dissect_unknown, dissect_unknown},
14486   /* 0x98 */  {dissect_unknown, dissect_unknown},
14487   /* 0x99 */  {dissect_unknown, dissect_unknown},
14488   /* 0x9a */  {dissect_unknown, dissect_unknown},
14489   /* 0x9b */  {dissect_unknown, dissect_unknown},
14490   /* 0x9c */  {dissect_unknown, dissect_unknown},
14491   /* 0x9d */  {dissect_unknown, dissect_unknown},
14492   /* 0x9e */  {dissect_unknown, dissect_unknown},
14493   /* 0x9f */  {dissect_unknown, dissect_unknown},
14494
14495   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
14496   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
14497   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
14498   /* 0xa3 */  {dissect_unknown, dissect_unknown},
14499   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
14500   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
14501   /* 0xa6 */  {dissect_unknown, dissect_unknown},
14502   /* 0xa7 */  {dissect_unknown, dissect_unknown},
14503   /* 0xa8 */  {dissect_unknown, dissect_unknown},
14504   /* 0xa9 */  {dissect_unknown, dissect_unknown},
14505   /* 0xaa */  {dissect_unknown, dissect_unknown},
14506   /* 0xab */  {dissect_unknown, dissect_unknown},
14507   /* 0xac */  {dissect_unknown, dissect_unknown},
14508   /* 0xad */  {dissect_unknown, dissect_unknown},
14509   /* 0xae */  {dissect_unknown, dissect_unknown},
14510   /* 0xaf */  {dissect_unknown, dissect_unknown},
14511
14512   /* 0xb0 */  {dissect_unknown, dissect_unknown},
14513   /* 0xb1 */  {dissect_unknown, dissect_unknown},
14514   /* 0xb2 */  {dissect_unknown, dissect_unknown},
14515   /* 0xb3 */  {dissect_unknown, dissect_unknown},
14516   /* 0xb4 */  {dissect_unknown, dissect_unknown},
14517   /* 0xb5 */  {dissect_unknown, dissect_unknown},
14518   /* 0xb6 */  {dissect_unknown, dissect_unknown},
14519   /* 0xb7 */  {dissect_unknown, dissect_unknown},
14520   /* 0xb8 */  {dissect_unknown, dissect_unknown},
14521   /* 0xb9 */  {dissect_unknown, dissect_unknown},
14522   /* 0xba */  {dissect_unknown, dissect_unknown},
14523   /* 0xbb */  {dissect_unknown, dissect_unknown},
14524   /* 0xbc */  {dissect_unknown, dissect_unknown},
14525   /* 0xbd */  {dissect_unknown, dissect_unknown},
14526   /* 0xbe */  {dissect_unknown, dissect_unknown},
14527   /* 0xbf */  {dissect_unknown, dissect_unknown},
14528
14529   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
14530   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
14531   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
14532   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
14533   /* 0xc4 */  {dissect_unknown, dissect_unknown},
14534   /* 0xc5 */  {dissect_unknown, dissect_unknown},
14535   /* 0xc6 */  {dissect_unknown, dissect_unknown},
14536   /* 0xc7 */  {dissect_unknown, dissect_unknown},
14537   /* 0xc8 */  {dissect_unknown, dissect_unknown},
14538   /* 0xc9 */  {dissect_unknown, dissect_unknown},
14539   /* 0xca */  {dissect_unknown, dissect_unknown},
14540   /* 0xcb */  {dissect_unknown, dissect_unknown},
14541   /* 0xcc */  {dissect_unknown, dissect_unknown},
14542   /* 0xcd */  {dissect_unknown, dissect_unknown},
14543   /* 0xce */  {dissect_unknown, dissect_unknown},
14544   /* 0xcf */  {dissect_unknown, dissect_unknown},
14545
14546   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
14547   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
14548   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
14549   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
14550   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
14551   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
14552   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
14553   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
14554   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
14555   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
14556   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
14557   /* 0xdb */  {dissect_unknown, dissect_unknown},
14558   /* 0xdc */  {dissect_unknown, dissect_unknown},
14559   /* 0xdd */  {dissect_unknown, dissect_unknown},
14560   /* 0xde */  {dissect_unknown, dissect_unknown},
14561   /* 0xdf */  {dissect_unknown, dissect_unknown},
14562
14563   /* 0xe0 */  {dissect_unknown, dissect_unknown},
14564   /* 0xe1 */  {dissect_unknown, dissect_unknown},
14565   /* 0xe2 */  {dissect_unknown, dissect_unknown},
14566   /* 0xe3 */  {dissect_unknown, dissect_unknown},
14567   /* 0xe4 */  {dissect_unknown, dissect_unknown},
14568   /* 0xe5 */  {dissect_unknown, dissect_unknown},
14569   /* 0xe6 */  {dissect_unknown, dissect_unknown},
14570   /* 0xe7 */  {dissect_unknown, dissect_unknown},
14571   /* 0xe8 */  {dissect_unknown, dissect_unknown},
14572   /* 0xe9 */  {dissect_unknown, dissect_unknown},
14573   /* 0xea */  {dissect_unknown, dissect_unknown},
14574   /* 0xeb */  {dissect_unknown, dissect_unknown},
14575   /* 0xec */  {dissect_unknown, dissect_unknown},
14576   /* 0xed */  {dissect_unknown, dissect_unknown},
14577   /* 0xee */  {dissect_unknown, dissect_unknown},
14578   /* 0xef */  {dissect_unknown, dissect_unknown},
14579
14580   /* 0xf0 */  {dissect_unknown, dissect_unknown},
14581   /* 0xf1 */  {dissect_unknown, dissect_unknown},
14582   /* 0xf2 */  {dissect_unknown, dissect_unknown},
14583   /* 0xf3 */  {dissect_unknown, dissect_unknown},
14584   /* 0xf4 */  {dissect_unknown, dissect_unknown},
14585   /* 0xf5 */  {dissect_unknown, dissect_unknown},
14586   /* 0xf6 */  {dissect_unknown, dissect_unknown},
14587   /* 0xf7 */  {dissect_unknown, dissect_unknown},
14588   /* 0xf8 */  {dissect_unknown, dissect_unknown},
14589   /* 0xf9 */  {dissect_unknown, dissect_unknown},
14590   /* 0xfa */  {dissect_unknown, dissect_unknown},
14591   /* 0xfb */  {dissect_unknown, dissect_unknown},
14592   /* 0xfc */  {dissect_unknown, dissect_unknown},
14593   /* 0xfd */  {dissect_unknown, dissect_unknown},
14594   /* 0xfe */  {dissect_unknown, dissect_unknown},
14595   /* 0xff */  {dissect_unknown, dissect_unknown},
14596 };
14597
14598 static int
14599 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
14600 {
14601         smb_info_t *si;
14602
14603         si = pinfo->private_data;
14604         if(cmd!=0xff){
14605                 proto_item *cmd_item;
14606                 proto_tree *cmd_tree;
14607                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14608
14609                 if (check_col(pinfo->cinfo, COL_INFO)) {
14610                         if(first_pdu){
14611                                 col_append_fstr(pinfo->cinfo, COL_INFO,
14612                                         "%s %s",
14613                                         decode_smb_name(cmd),
14614                                         (si->request)? "Request" : "Response");
14615                         } else {
14616                                 col_append_fstr(pinfo->cinfo, COL_INFO,
14617                                         "; %s",
14618                                         decode_smb_name(cmd));
14619                         }
14620
14621                 }
14622
14623                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
14624                         "%s %s (0x%02x)",
14625                         decode_smb_name(cmd),
14626                         (si->request)?"Request":"Response",
14627                         cmd);
14628
14629                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
14630
14631                 dissector = (si->request)?
14632                         smb_dissector[cmd].request:smb_dissector[cmd].response;
14633
14634                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
14635                 proto_item_set_end(cmd_item, tvb, offset);
14636         }
14637         return offset;
14638 }
14639
14640
14641 /* NOTE: this value_string array will also be used to access data directly by
14642  * index instead of val_to_str() since
14643  * 1, the array will always span every value from 0x00 to 0xff and
14644  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
14645  * This means that this value_string array MUST always
14646  * 1, contain all entries 0x00 to 0xff
14647  * 2, all entries must be in order.
14648  */
14649 const value_string smb_cmd_vals[] = {
14650   { 0x00, "Create Directory" },
14651   { 0x01, "Delete Directory" },
14652   { 0x02, "Open" },
14653   { 0x03, "Create" },
14654   { 0x04, "Close" },
14655   { 0x05, "Flush" },
14656   { 0x06, "Delete" },
14657   { 0x07, "Rename" },
14658   { 0x08, "Query Information" },
14659   { 0x09, "Set Information" },
14660   { 0x0A, "Read" },
14661   { 0x0B, "Write" },
14662   { 0x0C, "Lock Byte Range" },
14663   { 0x0D, "Unlock Byte Range" },
14664   { 0x0E, "Create Temp" },
14665   { 0x0F, "Create New" },
14666   { 0x10, "Check Directory" },
14667   { 0x11, "Process Exit" },
14668   { 0x12, "Seek" },
14669   { 0x13, "Lock And Read" },
14670   { 0x14, "Write And Unlock" },
14671   { 0x15, "unknown-0x15" },
14672   { 0x16, "unknown-0x16" },
14673   { 0x17, "unknown-0x17" },
14674   { 0x18, "unknown-0x18" },
14675   { 0x19, "unknown-0x19" },
14676   { 0x1A, "Read Raw" },
14677   { 0x1B, "Read MPX" },
14678   { 0x1C, "Read MPX Secondary" },
14679   { 0x1D, "Write Raw" },
14680   { 0x1E, "Write MPX" },
14681   { 0x1F, "Write MPX Secondary" },
14682   { 0x20, "Write Complete" },
14683   { 0x21, "unknown-0x21" },
14684   { 0x22, "Set Information2" },
14685   { 0x23, "Query Information2" },
14686   { 0x24, "Locking AndX" },
14687   { 0x25, "Trans" },
14688   { 0x26, "Trans Secondary" },
14689   { 0x27, "IOCTL" },
14690   { 0x28, "IOCTL Secondary" },
14691   { 0x29, "Copy" },
14692   { 0x2A, "Move" },
14693   { 0x2B, "Echo" },
14694   { 0x2C, "Write And Close" },
14695   { 0x2D, "Open AndX" },
14696   { 0x2E, "Read AndX" },
14697   { 0x2F, "Write AndX" },
14698   { 0x30, "unknown-0x30" },
14699   { 0x31, "Close And Tree Disconnect" },
14700   { 0x32, "Trans2" },
14701   { 0x33, "Trans2 Secondary" },
14702   { 0x34, "Find Close2" },
14703   { 0x35, "Find Notify Close" },
14704   { 0x36, "unknown-0x36" },
14705   { 0x37, "unknown-0x37" },
14706   { 0x38, "unknown-0x38" },
14707   { 0x39, "unknown-0x39" },
14708   { 0x3A, "unknown-0x3A" },
14709   { 0x3B, "unknown-0x3B" },
14710   { 0x3C, "unknown-0x3C" },
14711   { 0x3D, "unknown-0x3D" },
14712   { 0x3E, "unknown-0x3E" },
14713   { 0x3F, "unknown-0x3F" },
14714   { 0x40, "unknown-0x40" },
14715   { 0x41, "unknown-0x41" },
14716   { 0x42, "unknown-0x42" },
14717   { 0x43, "unknown-0x43" },
14718   { 0x44, "unknown-0x44" },
14719   { 0x45, "unknown-0x45" },
14720   { 0x46, "unknown-0x46" },
14721   { 0x47, "unknown-0x47" },
14722   { 0x48, "unknown-0x48" },
14723   { 0x49, "unknown-0x49" },
14724   { 0x4A, "unknown-0x4A" },
14725   { 0x4B, "unknown-0x4B" },
14726   { 0x4C, "unknown-0x4C" },
14727   { 0x4D, "unknown-0x4D" },
14728   { 0x4E, "unknown-0x4E" },
14729   { 0x4F, "unknown-0x4F" },
14730   { 0x50, "unknown-0x50" },
14731   { 0x51, "unknown-0x51" },
14732   { 0x52, "unknown-0x52" },
14733   { 0x53, "unknown-0x53" },
14734   { 0x54, "unknown-0x54" },
14735   { 0x55, "unknown-0x55" },
14736   { 0x56, "unknown-0x56" },
14737   { 0x57, "unknown-0x57" },
14738   { 0x58, "unknown-0x58" },
14739   { 0x59, "unknown-0x59" },
14740   { 0x5A, "unknown-0x5A" },
14741   { 0x5B, "unknown-0x5B" },
14742   { 0x5C, "unknown-0x5C" },
14743   { 0x5D, "unknown-0x5D" },
14744   { 0x5E, "unknown-0x5E" },
14745   { 0x5F, "unknown-0x5F" },
14746   { 0x60, "unknown-0x60" },
14747   { 0x61, "unknown-0x61" },
14748   { 0x62, "unknown-0x62" },
14749   { 0x63, "unknown-0x63" },
14750   { 0x64, "unknown-0x64" },
14751   { 0x65, "unknown-0x65" },
14752   { 0x66, "unknown-0x66" },
14753   { 0x67, "unknown-0x67" },
14754   { 0x68, "unknown-0x68" },
14755   { 0x69, "unknown-0x69" },
14756   { 0x6A, "unknown-0x6A" },
14757   { 0x6B, "unknown-0x6B" },
14758   { 0x6C, "unknown-0x6C" },
14759   { 0x6D, "unknown-0x6D" },
14760   { 0x6E, "unknown-0x6E" },
14761   { 0x6F, "unknown-0x6F" },
14762   { 0x70, "Tree Connect" },
14763   { 0x71, "Tree Disconnect" },
14764   { 0x72, "Negotiate Protocol" },
14765   { 0x73, "Session Setup AndX" },
14766   { 0x74, "Logoff AndX" },
14767   { 0x75, "Tree Connect AndX" },
14768   { 0x76, "unknown-0x76" },
14769   { 0x77, "unknown-0x77" },
14770   { 0x78, "unknown-0x78" },
14771   { 0x79, "unknown-0x79" },
14772   { 0x7A, "unknown-0x7A" },
14773   { 0x7B, "unknown-0x7B" },
14774   { 0x7C, "unknown-0x7C" },
14775   { 0x7D, "unknown-0x7D" },
14776   { 0x7E, "unknown-0x7E" },
14777   { 0x7F, "unknown-0x7F" },
14778   { 0x80, "Query Information Disk" },
14779   { 0x81, "Search" },
14780   { 0x82, "Find" },
14781   { 0x83, "Find Unique" },
14782   { 0x84, "Find Close" },
14783   { 0x85, "unknown-0x85" },
14784   { 0x86, "unknown-0x86" },
14785   { 0x87, "unknown-0x87" },
14786   { 0x88, "unknown-0x88" },
14787   { 0x89, "unknown-0x89" },
14788   { 0x8A, "unknown-0x8A" },
14789   { 0x8B, "unknown-0x8B" },
14790   { 0x8C, "unknown-0x8C" },
14791   { 0x8D, "unknown-0x8D" },
14792   { 0x8E, "unknown-0x8E" },
14793   { 0x8F, "unknown-0x8F" },
14794   { 0x90, "unknown-0x90" },
14795   { 0x91, "unknown-0x91" },
14796   { 0x92, "unknown-0x92" },
14797   { 0x93, "unknown-0x93" },
14798   { 0x94, "unknown-0x94" },
14799   { 0x95, "unknown-0x95" },
14800   { 0x96, "unknown-0x96" },
14801   { 0x97, "unknown-0x97" },
14802   { 0x98, "unknown-0x98" },
14803   { 0x99, "unknown-0x99" },
14804   { 0x9A, "unknown-0x9A" },
14805   { 0x9B, "unknown-0x9B" },
14806   { 0x9C, "unknown-0x9C" },
14807   { 0x9D, "unknown-0x9D" },
14808   { 0x9E, "unknown-0x9E" },
14809   { 0x9F, "unknown-0x9F" },
14810   { 0xA0, "NT Trans" },
14811   { 0xA1, "NT Trans Secondary" },
14812   { 0xA2, "NT Create AndX" },
14813   { 0xA3, "unknown-0xA3" },
14814   { 0xA4, "NT Cancel" },
14815   { 0xA5, "NT Rename" },
14816   { 0xA6, "unknown-0xA6" },
14817   { 0xA7, "unknown-0xA7" },
14818   { 0xA8, "unknown-0xA8" },
14819   { 0xA9, "unknown-0xA9" },
14820   { 0xAA, "unknown-0xAA" },
14821   { 0xAB, "unknown-0xAB" },
14822   { 0xAC, "unknown-0xAC" },
14823   { 0xAD, "unknown-0xAD" },
14824   { 0xAE, "unknown-0xAE" },
14825   { 0xAF, "unknown-0xAF" },
14826   { 0xB0, "unknown-0xB0" },
14827   { 0xB1, "unknown-0xB1" },
14828   { 0xB2, "unknown-0xB2" },
14829   { 0xB3, "unknown-0xB3" },
14830   { 0xB4, "unknown-0xB4" },
14831   { 0xB5, "unknown-0xB5" },
14832   { 0xB6, "unknown-0xB6" },
14833   { 0xB7, "unknown-0xB7" },
14834   { 0xB8, "unknown-0xB8" },
14835   { 0xB9, "unknown-0xB9" },
14836   { 0xBA, "unknown-0xBA" },
14837   { 0xBB, "unknown-0xBB" },
14838   { 0xBC, "unknown-0xBC" },
14839   { 0xBD, "unknown-0xBD" },
14840   { 0xBE, "unknown-0xBE" },
14841   { 0xBF, "unknown-0xBF" },
14842   { 0xC0, "Open Print File" },
14843   { 0xC1, "Write Print File" },
14844   { 0xC2, "Close Print File" },
14845   { 0xC3, "Get Print Queue" },
14846   { 0xC4, "unknown-0xC4" },
14847   { 0xC5, "unknown-0xC5" },
14848   { 0xC6, "unknown-0xC6" },
14849   { 0xC7, "unknown-0xC7" },
14850   { 0xC8, "unknown-0xC8" },
14851   { 0xC9, "unknown-0xC9" },
14852   { 0xCA, "unknown-0xCA" },
14853   { 0xCB, "unknown-0xCB" },
14854   { 0xCC, "unknown-0xCC" },
14855   { 0xCD, "unknown-0xCD" },
14856   { 0xCE, "unknown-0xCE" },
14857   { 0xCF, "unknown-0xCF" },
14858   { 0xD0, "Send Single Block Message" },
14859   { 0xD1, "Send Broadcast Message" },
14860   { 0xD2, "Forward User Name" },
14861   { 0xD3, "Cancel Forward" },
14862   { 0xD4, "Get Machine Name" },
14863   { 0xD5, "Send Start of Multi-block Message" },
14864   { 0xD6, "Send End of Multi-block Message" },
14865   { 0xD7, "Send Text of Multi-block Message" },
14866   { 0xD8, "SMBreadbulk" },
14867   { 0xD9, "SMBwritebulk" },
14868   { 0xDA, "SMBwritebulkdata" },
14869   { 0xDB, "unknown-0xDB" },
14870   { 0xDC, "unknown-0xDC" },
14871   { 0xDD, "unknown-0xDD" },
14872   { 0xDE, "unknown-0xDE" },
14873   { 0xDF, "unknown-0xDF" },
14874   { 0xE0, "unknown-0xE0" },
14875   { 0xE1, "unknown-0xE1" },
14876   { 0xE2, "unknown-0xE2" },
14877   { 0xE3, "unknown-0xE3" },
14878   { 0xE4, "unknown-0xE4" },
14879   { 0xE5, "unknown-0xE5" },
14880   { 0xE6, "unknown-0xE6" },
14881   { 0xE7, "unknown-0xE7" },
14882   { 0xE8, "unknown-0xE8" },
14883   { 0xE9, "unknown-0xE9" },
14884   { 0xEA, "unknown-0xEA" },
14885   { 0xEB, "unknown-0xEB" },
14886   { 0xEC, "unknown-0xEC" },
14887   { 0xED, "unknown-0xED" },
14888   { 0xEE, "unknown-0xEE" },
14889   { 0xEF, "unknown-0xEF" },
14890   { 0xF0, "unknown-0xF0" },
14891   { 0xF1, "unknown-0xF1" },
14892   { 0xF2, "unknown-0xF2" },
14893   { 0xF3, "unknown-0xF3" },
14894   { 0xF4, "unknown-0xF4" },
14895   { 0xF5, "unknown-0xF5" },
14896   { 0xF6, "unknown-0xF6" },
14897   { 0xF7, "unknown-0xF7" },
14898   { 0xF8, "unknown-0xF8" },
14899   { 0xF9, "unknown-0xF9" },
14900   { 0xFA, "unknown-0xFA" },
14901   { 0xFB, "unknown-0xFB" },
14902   { 0xFC, "unknown-0xFC" },
14903   { 0xFD, "unknown-0xFD" },
14904   { 0xFE, "SMBinvalid" },
14905   { 0xFF, "unknown-0xFF" },
14906   { 0x00, NULL },
14907 };
14908
14909 static char *decode_smb_name(unsigned char cmd)
14910 {
14911   return(smb_cmd_vals[cmd].strptr);
14912 }
14913
14914
14915
14916 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14917  * Everything TVBUFFIFIED above this line
14918  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
14919
14920
14921 static void
14922 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
14923 {
14924         conv_tables_t *ct = ctarg;
14925
14926         if (ct->unmatched)
14927                 g_hash_table_destroy(ct->unmatched);
14928         if (ct->matched)
14929                 g_hash_table_destroy(ct->matched);
14930         if (ct->tid_service)
14931                 g_hash_table_destroy(ct->tid_service);
14932 }
14933
14934 static void
14935 smb_init_protocol(void)
14936 {
14937         if (smb_saved_info_key_chunk)
14938                 g_mem_chunk_destroy(smb_saved_info_key_chunk);
14939         if (smb_saved_info_chunk)
14940                 g_mem_chunk_destroy(smb_saved_info_chunk);
14941         if (smb_nt_transact_info_chunk)
14942                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
14943         if (smb_transact2_info_chunk)
14944                 g_mem_chunk_destroy(smb_transact2_info_chunk);
14945         if (smb_transact_info_chunk)
14946                 g_mem_chunk_destroy(smb_transact_info_chunk);
14947
14948         /*
14949          * Free the hash tables attached to the conversation table
14950          * structures, and then free the list of conversation table
14951          * data structures (which doesn't free the data structures
14952          * themselves; that's done by destroying the chunk from
14953          * which they were allocated).
14954          */
14955         if (conv_tables) {
14956                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
14957                 g_slist_free(conv_tables);
14958                 conv_tables = NULL;
14959         }
14960
14961         /*
14962          * Now destroy the chunk from which the conversation table
14963          * structures were allocated.
14964          */
14965         if (conv_tables_chunk)
14966                 g_mem_chunk_destroy(conv_tables_chunk);
14967
14968         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
14969             sizeof(smb_saved_info_t),
14970             smb_saved_info_init_count * sizeof(smb_saved_info_t),
14971             G_ALLOC_ONLY);
14972         smb_saved_info_key_chunk = g_mem_chunk_new("smb_saved_info_key_chunk",
14973             sizeof(smb_saved_info_key_t),
14974             smb_saved_info_init_count * sizeof(smb_saved_info_key_t),
14975             G_ALLOC_ONLY);
14976         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
14977             sizeof(smb_nt_transact_info_t),
14978             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
14979             G_ALLOC_ONLY);
14980         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
14981             sizeof(smb_transact2_info_t),
14982             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
14983             G_ALLOC_ONLY);
14984         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
14985             sizeof(smb_transact_info_t),
14986             smb_transact_info_init_count * sizeof(smb_transact_info_t),
14987             G_ALLOC_ONLY);
14988         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
14989             sizeof(conv_tables_t),
14990             conv_tables_count * sizeof(conv_tables_t),
14991             G_ALLOC_ONLY);
14992 }
14993
14994 static const value_string errcls_types[] = {
14995   { SMB_SUCCESS, "Success"},
14996   { SMB_ERRDOS, "DOS Error"},
14997   { SMB_ERRSRV, "Server Error"},
14998   { SMB_ERRHRD, "Hardware Error"},
14999   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
15000   { 0, NULL }
15001 };
15002
15003 const value_string DOS_errors[] = {
15004   {0, "Success"},
15005   {SMBE_insufficientbuffer, "Insufficient buffer"},
15006   {SMBE_badfunc, "Invalid function (or system call)"},
15007   {SMBE_badfile, "File not found (pathname error)"},
15008   {SMBE_badpath, "Directory not found"},
15009   {SMBE_nofids, "Too many open files"},
15010   {SMBE_noaccess, "Access denied"},
15011   {SMBE_badfid, "Invalid fid"},
15012   {SMBE_nomem,  "Out of memory"},
15013   {SMBE_badmem, "Invalid memory block address"},
15014   {SMBE_badenv, "Invalid environment"},
15015   {SMBE_badaccess, "Invalid open mode"},
15016   {SMBE_baddata, "Invalid data (only from ioctl call)"},
15017   {SMBE_res, "Reserved error code?"},
15018   {SMBE_baddrive, "Invalid drive"},
15019   {SMBE_remcd, "Attempt to delete current directory"},
15020   {SMBE_diffdevice, "Rename/move across different filesystems"},
15021   {SMBE_nofiles, "No more files found in file search"},
15022   {SMBE_badshare, "Share mode on file conflict with open mode"},
15023   {SMBE_lock, "Lock request conflicts with existing lock"},
15024   {SMBE_unsup, "Request unsupported, returned by Win 95"},
15025   {SMBE_nosuchshare, "Requested share does not exist"},
15026   {SMBE_filexists, "File in operation already exists"},
15027   {SMBE_cannotopen, "Cannot open the file specified"},
15028   {SMBE_unknownlevel, "Unknown info level"},
15029   {SMBE_invalidname, "Invalid name"},
15030   {SMBE_badpipe, "Named pipe invalid"},
15031   {SMBE_pipebusy, "All instances of pipe are busy"},
15032   {SMBE_pipeclosing, "Named pipe close in progress"},
15033   {SMBE_notconnected, "No process on other end of named pipe"},
15034   {SMBE_moredata, "More data to be returned"},
15035   {SMBE_baddirectory,  "Invalid directory name in a path."},
15036   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
15037   {SMBE_eas_nsup, "Extended attributes not supported"},
15038   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
15039   {SMBE_unknownipc, "Unknown IPC Operation"},
15040   {SMBE_noipc, "Don't support ipc"},
15041   {SMBE_alreadyexists, "File already exists"},
15042   {SMBE_unknownprinterdriver, "Unknown printer driver"},
15043   {SMBE_invalidprintername, "Invalid printer name"},
15044   {SMBE_printeralreadyexists, "Printer already exists"},
15045   {SMBE_invaliddatatype, "Invalid data type"},
15046   {SMBE_invalidenvironment, "Invalid environment"},
15047   {SMBE_printerdriverinuse, "Printer driver in use"},
15048   {SMBE_invalidparam, "Invalid parameter"},
15049   {SMBE_invalidformsize, "Invalid form size"},
15050   {SMBE_invalidsecuritydescriptor, "Invalid security descriptor"},
15051   {SMBE_invalidowner, "Invalid owner"},
15052   {SMBE_nomoreitems, "No more items"},
15053   {SMBE_serverunavailable, "Server unavailable"},
15054   {0, NULL}
15055   };
15056
15057 /* Error codes for the ERRSRV class */
15058
15059 static const value_string SRV_errors[] = {
15060   {SMBE_error, "Non specific error code"},
15061   {SMBE_badpw, "Bad password"},
15062   {SMBE_badtype, "Reserved"},
15063   {SMBE_access, "No permissions to perform the requested operation"},
15064   {SMBE_invnid, "TID invalid"},
15065   {SMBE_invnetname, "Invalid network name. Service not found"},
15066   {SMBE_invdevice, "Invalid device"},
15067   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
15068   {SMBE_qfull, "Print queue full"},
15069   {SMBE_qtoobig, "Queued item too big"},
15070   {SMBE_qeof, "EOF on print queue dump"},
15071   {SMBE_invpfid, "Invalid print file in smb_fid"},
15072   {SMBE_smbcmd, "Unrecognised command"},
15073   {SMBE_srverror, "SMB server internal error"},
15074   {SMBE_filespecs, "Fid and pathname invalid combination"},
15075   {SMBE_badlink, "Bad link in request ???"},
15076   {SMBE_badpermits, "Access specified for a file is not valid"},
15077   {SMBE_badpid, "Bad process id in request"},
15078   {SMBE_setattrmode, "Attribute mode invalid"},
15079   {SMBE_paused, "Message server paused"},
15080   {SMBE_msgoff, "Not receiving messages"},
15081   {SMBE_noroom, "No room for message"},
15082   {SMBE_rmuns, "Too many remote usernames"},
15083   {SMBE_timeout, "Operation timed out"},
15084   {SMBE_noresource, "No resources currently available for request."},
15085   {SMBE_toomanyuids, "Too many userids"},
15086   {SMBE_baduid, "Bad userid"},
15087   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
15088   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
15089   {SMBE_contMPX, "Resume MPX mode"},
15090   {SMBE_badPW, "Bad Password???"},
15091   {SMBE_nosupport, "Operation not supported"},
15092   { 0, NULL}
15093 };
15094
15095 /* Error codes for the ERRHRD class */
15096
15097 static const value_string HRD_errors[] = {
15098   {SMBE_nowrite, "Read only media"},
15099   {SMBE_badunit, "Unknown device"},
15100   {SMBE_notready, "Drive not ready"},
15101   {SMBE_badcmd, "Unknown command"},
15102   {SMBE_data, "Data (CRC) error"},
15103   {SMBE_badreq, "Bad request structure length"},
15104   {SMBE_seek, "Seek error"},
15105   {SMBE_badmedia, "Unknown media type"},
15106   {SMBE_badsector, "Sector not found"},
15107   {SMBE_nopaper, "Printer out of paper"},
15108   {SMBE_write, "Write fault"},
15109   {SMBE_read, "Read fault"},
15110   {SMBE_general, "General failure"},
15111   {SMBE_badshare, "A open conflicts with an existing open"},
15112   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
15113   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
15114   {SMBE_FCBunavail, "No FCBs are available to process request"},
15115   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
15116   {SMBE_diskfull, "Disk full???"},
15117   {0, NULL}
15118 };
15119
15120 static char *decode_smb_error(guint8 errcls, guint16 errcode)
15121 {
15122
15123   switch (errcls) {
15124
15125   case SMB_SUCCESS:
15126
15127     return("No Error");   /* No error ??? */
15128     break;
15129
15130   case SMB_ERRDOS:
15131
15132     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
15133     break;
15134
15135   case SMB_ERRSRV:
15136
15137     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
15138     break;
15139
15140   case SMB_ERRHRD:
15141
15142     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
15143     break;
15144
15145   default:
15146
15147     return("Unknown error class!");
15148
15149   }
15150
15151 }
15152
15153
15154 /* These are the MS country codes from
15155
15156         http://www.unicode.org/unicode/onlinedat/countries.html
15157
15158    For countries that share the same number, I choose to use only the
15159    name of the largest country. Apologies for this. If this offends you,
15160    here is the table to change that.
15161
15162    This also includes the code of 0 for "Default", which isn't in
15163    that list, but is in Microsoft's SDKs and the Cygnus "winnls.h"
15164    header file.  Presumably it means "don't override the setting
15165    on the user's machine".
15166
15167    Future versions of Microsoft's "winnls.h" header file might include
15168    additional codes; the current version matches the Unicode Consortium's
15169    table.
15170 */
15171 const value_string ms_country_codes[] = {
15172         {  0,   "Default"},
15173         {  1,   "USA"},
15174         {  2,   "Canada"},
15175         {  7,   "Russia"},
15176         { 20,   "Egypt"},
15177         { 27,   "South Africa"},
15178         { 30,   "Greece"},
15179         { 31,   "Netherlands"},
15180         { 32,   "Belgium"},
15181         { 33,   "France"},
15182         { 34,   "Spain"},
15183         { 36,   "Hungary"},
15184         { 39,   "Italy"},
15185         { 40,   "Romania"},
15186         { 41,   "Switzerland"},
15187         { 43,   "Austria"},
15188         { 44,   "United Kingdom"},
15189         { 45,   "Denmark"},
15190         { 46,   "Sweden"},
15191         { 47,   "Norway"},
15192         { 48,   "Poland"},
15193         { 49,   "Germany"},
15194         { 51,   "Peru"},
15195         { 52,   "Mexico"},
15196         { 54,   "Argentina"},
15197         { 55,   "Brazil"},
15198         { 56,   "Chile"},
15199         { 57,   "Colombia"},
15200         { 58,   "Venezuela"},
15201         { 60,   "Malaysia"},
15202         { 61,   "Australia"},
15203         { 62,   "Indonesia"},
15204         { 63,   "Philippines"},
15205         { 64,   "New Zealand"},
15206         { 65,   "Singapore"},
15207         { 66,   "Thailand"},
15208         { 81,   "Japan"},
15209         { 82,   "South Korea"},
15210         { 84,   "Viet Nam"},
15211         { 86,   "China"},
15212         { 90,   "Turkey"},
15213         { 91,   "India"},
15214         { 92,   "Pakistan"},
15215         {212,   "Morocco"},
15216         {213,   "Algeria"},
15217         {216,   "Tunisia"},
15218         {218,   "Libya"},
15219         {254,   "Kenya"},
15220         {263,   "Zimbabwe"},
15221         {298,   "Faroe Islands"},
15222         {351,   "Portugal"},
15223         {352,   "Luxembourg"},
15224         {353,   "Ireland"},
15225         {354,   "Iceland"},
15226         {355,   "Albania"},
15227         {358,   "Finland"},
15228         {359,   "Bulgaria"},
15229         {370,   "Lithuania"},
15230         {371,   "Latvia"},
15231         {372,   "Estonia"},
15232         {374,   "Armenia"},
15233         {375,   "Belarus"},
15234         {380,   "Ukraine"},
15235         {381,   "Serbia"},
15236         {385,   "Croatia"},
15237         {386,   "Slovenia"},
15238         {389,   "Macedonia"},
15239         {420,   "Czech Republic"},
15240         {421,   "Slovak Republic"},
15241         {501,   "Belize"},
15242         {502,   "Guatemala"},
15243         {503,   "El Salvador"},
15244         {504,   "Honduras"},
15245         {505,   "Nicaragua"},
15246         {506,   "Costa Rica"},
15247         {507,   "Panama"},
15248         {591,   "Bolivia"},
15249         {593,   "Ecuador"},
15250         {595,   "Paraguay"},
15251         {598,   "Uruguay"},
15252         {673,   "Brunei Darussalam"},
15253         {852,   "Hong Kong"},
15254         {853,   "Macau"},
15255         {886,   "Taiwan"},
15256         {960,   "Maldives"},
15257         {961,   "Lebanon"},
15258         {962,   "Jordan"},
15259         {963,   "Syria"},
15260         {964,   "Iraq"},
15261         {965,   "Kuwait"},
15262         {966,   "Saudi Arabia"},
15263         {967,   "Yemen"},
15264         {968,   "Oman"},
15265         {971,   "United Arab Emirates"},
15266         {972,   "Israel"},
15267         {973,   "Bahrain"},
15268         {974,   "Qatar"},
15269         {976,   "Mongolia"},
15270         {981,   "Iran"},
15271         {994,   "Azerbaijan"},
15272         {995,   "Georgia"},
15273         {996,   "Kyrgyzstan"},
15274
15275         {0,     NULL}
15276 };
15277
15278 /*
15279  * NT error codes.
15280  *
15281  * From
15282  *
15283  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
15284  */
15285 const value_string NT_errors[] = {
15286   { 0x00000000, "STATUS_SUCCESS" },
15287   { 0x00000000, "STATUS_WAIT_0" },
15288   { 0x00000001, "STATUS_WAIT_1" },
15289   { 0x00000002, "STATUS_WAIT_2" },
15290   { 0x00000003, "STATUS_WAIT_3" },
15291   { 0x0000003F, "STATUS_WAIT_63" },
15292   { 0x00000080, "STATUS_ABANDONED" },
15293   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
15294   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
15295   { 0x000000C0, "STATUS_USER_APC" },
15296   { 0x00000100, "STATUS_KERNEL_APC" },
15297   { 0x00000101, "STATUS_ALERTED" },
15298   { 0x00000102, "STATUS_TIMEOUT" },
15299   { 0x00000103, "STATUS_PENDING" },
15300   { 0x00000104, "STATUS_REPARSE" },
15301   { 0x00000105, "STATUS_MORE_ENTRIES" },
15302   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
15303   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
15304   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
15305   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
15306   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
15307   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
15308   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
15309   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
15310   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
15311   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
15312   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
15313   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
15314   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
15315   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
15316   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
15317   { 0x00000116, "STATUS_CRASH_DUMP" },
15318   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
15319   { 0x00000118, "STATUS_REPARSE_OBJECT" },
15320   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
15321   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
15322   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
15323   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
15324   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
15325   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
15326   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
15327   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
15328   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
15329   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
15330   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
15331   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
15332   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
15333   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
15334   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
15335   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
15336   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
15337   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
15338   { 0x40000012, "STATUS_EVENT_DONE" },
15339   { 0x40000013, "STATUS_EVENT_PENDING" },
15340   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
15341   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
15342   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
15343   { 0x40000017, "STATUS_WAS_UNLOCKED" },
15344   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
15345   { 0x40000019, "STATUS_WAS_LOCKED" },
15346   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
15347   { 0x4000001B, "STATUS_ALREADY_WIN32" },
15348   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
15349   { 0x4000001D, "STATUS_WX86_CONTINUE" },
15350   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
15351   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
15352   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
15353   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
15354   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
15355   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
15356   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
15357   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
15358   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
15359   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
15360   { 0x80000003, "STATUS_BREAKPOINT" },
15361   { 0x80000004, "STATUS_SINGLE_STEP" },
15362   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
15363   { 0x80000006, "STATUS_NO_MORE_FILES" },
15364   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
15365   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
15366   { 0x8000000B, "STATUS_NO_INHERITANCE" },
15367   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
15368   { 0x8000000D, "STATUS_PARTIAL_COPY" },
15369   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
15370   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
15371   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
15372   { 0x80000011, "STATUS_DEVICE_BUSY" },
15373   { 0x80000012, "STATUS_NO_MORE_EAS" },
15374   { 0x80000013, "STATUS_INVALID_EA_NAME" },
15375   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
15376   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
15377   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
15378   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
15379   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
15380   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
15381   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
15382   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
15383   { 0x8000001D, "STATUS_BUS_RESET" },
15384   { 0x8000001E, "STATUS_END_OF_MEDIA" },
15385   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
15386   { 0x80000020, "STATUS_MEDIA_CHECK" },
15387   { 0x80000021, "STATUS_SETMARK_DETECTED" },
15388   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
15389   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
15390   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
15391   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
15392   { 0x80000026, "STATUS_LONGJUMP" },
15393   { 0x80040111, "MAPI_E_LOGON_FAILED" },
15394   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
15395   { 0x80090301, "SEC_E_INVALID_HANDLE" },
15396   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
15397   { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
15398   { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
15399   { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
15400   { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
15401   { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
15402   { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
15403   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
15404   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
15405   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
15406   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
15407   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
15408   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
15409   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
15410   { 0xC0000008, "STATUS_INVALID_HANDLE" },
15411   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
15412   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
15413   { 0xC000000B, "STATUS_INVALID_CID" },
15414   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
15415   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
15416   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
15417   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
15418   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
15419   { 0xC0000011, "STATUS_END_OF_FILE" },
15420   { 0xC0000012, "STATUS_WRONG_VOLUME" },
15421   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
15422   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
15423   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
15424   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
15425   { 0xC0000017, "STATUS_NO_MEMORY" },
15426   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
15427   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
15428   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
15429   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
15430   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
15431   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
15432   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
15433   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
15434   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
15435   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
15436   { 0xC0000022, "STATUS_ACCESS_DENIED" },
15437   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
15438   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
15439   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
15440   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
15441   { 0xC0000027, "STATUS_UNWIND" },
15442   { 0xC0000028, "STATUS_BAD_STACK" },
15443   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
15444   { 0xC000002A, "STATUS_NOT_LOCKED" },
15445   { 0xC000002B, "STATUS_PARITY_ERROR" },
15446   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
15447   { 0xC000002D, "STATUS_NOT_COMMITTED" },
15448   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
15449   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
15450   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
15451   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
15452   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
15453   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
15454   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
15455   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
15456   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
15457   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
15458   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
15459   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
15460   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
15461   { 0xC000003C, "STATUS_DATA_OVERRUN" },
15462   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
15463   { 0xC000003E, "STATUS_DATA_ERROR" },
15464   { 0xC000003F, "STATUS_CRC_ERROR" },
15465   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
15466   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
15467   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
15468   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
15469   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
15470   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
15471   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
15472   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
15473   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
15474   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
15475   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
15476   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
15477   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
15478   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
15479   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
15480   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
15481   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
15482   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
15483   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
15484   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
15485   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
15486   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
15487   { 0xC0000056, "STATUS_DELETE_PENDING" },
15488   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
15489   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
15490   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
15491   { 0xC000005A, "STATUS_INVALID_OWNER" },
15492   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
15493   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
15494   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
15495   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
15496   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
15497   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
15498   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
15499   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
15500   { 0xC0000063, "STATUS_USER_EXISTS" },
15501   { 0xC0000064, "STATUS_NO_SUCH_USER" },
15502   { 0xC0000065, "STATUS_GROUP_EXISTS" },
15503   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
15504   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
15505   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
15506   { 0xC0000069, "STATUS_LAST_ADMIN" },
15507   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
15508   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
15509   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
15510   { 0xC000006D, "STATUS_LOGON_FAILURE" },
15511   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
15512   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
15513   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
15514   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
15515   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
15516   { 0xC0000073, "STATUS_NONE_MAPPED" },
15517   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
15518   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
15519   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
15520   { 0xC0000077, "STATUS_INVALID_ACL" },
15521   { 0xC0000078, "STATUS_INVALID_SID" },
15522   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
15523   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
15524   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
15525   { 0xC000007C, "STATUS_NO_TOKEN" },
15526   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
15527   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
15528   { 0xC000007F, "STATUS_DISK_FULL" },
15529   { 0xC0000080, "STATUS_SERVER_DISABLED" },
15530   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
15531   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
15532   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
15533   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
15534   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
15535   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
15536   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
15537   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
15538   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
15539   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
15540   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
15541   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
15542   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
15543   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
15544   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
15545   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
15546   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
15547   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
15548   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
15549   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
15550   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
15551   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
15552   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
15553   { 0xC0000098, "STATUS_FILE_INVALID" },
15554   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
15555   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
15556   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
15557   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
15558   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
15559   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
15560   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
15561   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
15562   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
15563   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
15564   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
15565   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
15566   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
15567   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
15568   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
15569   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
15570   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
15571   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
15572   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
15573   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
15574   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
15575   { 0xC00000AE, "STATUS_PIPE_BUSY" },
15576   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
15577   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
15578   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
15579   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
15580   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
15581   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
15582   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
15583   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
15584   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
15585   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
15586   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
15587   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
15588   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
15589   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
15590   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
15591   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
15592   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
15593   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
15594   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
15595   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
15596   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
15597   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
15598   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
15599   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
15600   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
15601   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
15602   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
15603   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
15604   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
15605   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
15606   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
15607   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
15608   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
15609   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
15610   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
15611   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
15612   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
15613   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
15614   { 0xC00000D5, "STATUS_FILE_RENAMED" },
15615   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
15616   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
15617   { 0xC00000D8, "STATUS_CANT_WAIT" },
15618   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
15619   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
15620   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
15621   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
15622   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
15623   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
15624   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
15625   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
15626   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
15627   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
15628   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
15629   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
15630   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
15631   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
15632   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
15633   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
15634   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
15635   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
15636   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
15637   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
15638   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
15639   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
15640   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
15641   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
15642   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
15643   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
15644   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
15645   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
15646   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
15647   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
15648   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
15649   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
15650   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
15651   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
15652   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
15653   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
15654   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
15655   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
15656   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
15657   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
15658   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
15659   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
15660   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
15661   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
15662   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
15663   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
15664   { 0xC0000107, "STATUS_FILES_OPEN" },
15665   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
15666   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
15667   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
15668   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
15669   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
15670   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
15671   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
15672   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
15673   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
15674   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
15675   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
15676   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
15677   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
15678   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
15679   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
15680   { 0xC0000117, "STATUS_NO_LDT" },
15681   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
15682   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
15683   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
15684   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
15685   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
15686   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
15687   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
15688   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
15689   { 0xC0000120, "STATUS_CANCELLED" },
15690   { 0xC0000121, "STATUS_CANNOT_DELETE" },
15691   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
15692   { 0xC0000123, "STATUS_FILE_DELETED" },
15693   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
15694   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
15695   { 0xC0000126, "STATUS_SPECIAL_USER" },
15696   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
15697   { 0xC0000128, "STATUS_FILE_CLOSED" },
15698   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
15699   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
15700   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
15701   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
15702   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
15703   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
15704   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
15705   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
15706   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
15707   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
15708   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
15709   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
15710   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
15711   { 0xC0000136, "STATUS_OPEN_FAILED" },
15712   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
15713   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
15714   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
15715   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
15716   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
15717   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
15718   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
15719   { 0xC000013E, "STATUS_LINK_FAILED" },
15720   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
15721   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
15722   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
15723   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
15724   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
15725   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
15726   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
15727   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
15728   { 0xC0000147, "STATUS_NO_PAGEFILE" },
15729   { 0xC0000148, "STATUS_INVALID_LEVEL" },
15730   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
15731   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
15732   { 0xC000014B, "STATUS_PIPE_BROKEN" },
15733   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
15734   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
15735   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
15736   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
15737   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
15738   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
15739   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
15740   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
15741   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
15742   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
15743   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
15744   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
15745   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
15746   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
15747   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
15748   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
15749   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
15750   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
15751   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
15752   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
15753   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
15754   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
15755   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
15756   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
15757   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
15758   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
15759   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
15760   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
15761   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
15762   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
15763   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
15764   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
15765   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
15766   { 0xC000016D, "STATUS_FT_ORPHANING" },
15767   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
15768   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
15769   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
15770   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
15771   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
15772   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
15773   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
15774   { 0xC0000178, "STATUS_NO_MEDIA" },
15775   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
15776   { 0xC000017B, "STATUS_INVALID_MEMBER" },
15777   { 0xC000017C, "STATUS_KEY_DELETED" },
15778   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
15779   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
15780   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
15781   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
15782   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
15783   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
15784   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
15785   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
15786   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
15787   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
15788   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
15789   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
15790   { 0xC0000189, "STATUS_TOO_LATE" },
15791   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
15792   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
15793   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
15794   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
15795   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
15796   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
15797   { 0xC0000190, "STATUS_TRUST_FAILURE" },
15798   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
15799   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
15800   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
15801   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
15802   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
15803   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
15804   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
15805   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
15806   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
15807   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
15808   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
15809   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
15810   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
15811   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
15812   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
15813   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
15814   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
15815   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
15816   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
15817   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
15818   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
15819   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
15820   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
15821   { 0xC000020D, "STATUS_CONNECTION_RESET" },
15822   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
15823   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
15824   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
15825   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
15826   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
15827   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
15828   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
15829   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
15830   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
15831   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
15832   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
15833   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
15834   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
15835   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
15836   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
15837   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
15838   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
15839   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
15840   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
15841   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
15842   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
15843   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
15844   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
15845   { 0xC0000225, "STATUS_NOT_FOUND" },
15846   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
15847   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
15848   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
15849   { 0xC0000229, "STATUS_FAIL_CHECK" },
15850   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
15851   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
15852   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
15853   { 0xC000022D, "STATUS_RETRY" },
15854   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
15855   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
15856   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
15857   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
15858   { 0xC0000232, "STATUS_INVALID_VARIANT" },
15859   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
15860   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
15861   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
15862   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
15863   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
15864   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
15865   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
15866   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
15867   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
15868   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
15869   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
15870   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
15871   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
15872   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
15873   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
15874   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
15875   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
15876   { 0xC0000244, "STATUS_AUDIT_FAILED" },
15877   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
15878   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
15879   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
15880   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
15881   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
15882   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
15883   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
15884   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
15885   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
15886   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
15887   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
15888   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
15889   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
15890   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
15891   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
15892   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
15893   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
15894   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
15895   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
15896   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
15897   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
15898   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
15899   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
15900   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
15901   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
15902   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
15903   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
15904   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
15905   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
15906   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
15907   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
15908   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
15909   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
15910   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
15911   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
15912   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
15913   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
15914   { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
15915   { 0xC0000272, "STATUS_NO_MATCH" },
15916   { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
15917   { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
15918   { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
15919   { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
15920   { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
15921   { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
15922   { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
15923   { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
15924   { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
15925   { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
15926   { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
15927   { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
15928   { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
15929   { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
15930   { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
15931   { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
15932   { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
15933   { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
15934   { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
15935   { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
15936   { 0xC000028E, "STATUS_NO_EFS" },
15937   { 0xC000028F, "STATUS_WRONG_EFS" },
15938   { 0xC0000290, "STATUS_NO_USER_KEYS" },
15939   { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
15940   { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
15941   { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
15942   { 0x40000294, "STATUS_WAKE_SYSTEM" },
15943   { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
15944   { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
15945   { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
15946   { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
15947   { 0xC0000299, "STATUS_SHARED_POLICY" },
15948   { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
15949   { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
15950   { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
15951   { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
15952   { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
15953   { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
15954   { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
15955   { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
15956   { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
15957   { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
15958   { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
15959   { 0xC00002A5, "STATUS_DS_BUSY" },
15960   { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
15961   { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
15962   { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
15963   { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
15964   { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
15965   { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
15966   { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
15967   { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
15968   { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
15969   { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
15970   { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
15971   { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
15972   { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
15973   { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
15974   { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
15975   { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
15976   { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
15977   { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
15978   { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
15979   { 0xC00002B9, "STATUS_NOINTERFACE" },
15980   { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
15981   { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
15982   { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
15983   { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
15984   { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
15985   { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
15986   { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
15987   { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
15988   { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
15989   { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
15990   { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
15991   { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
15992   { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
15993   { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
15994   { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
15995   { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
15996   { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
15997   { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
15998   { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
15999   { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
16000   { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
16001   { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
16002   { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
16003   { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
16004   { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
16005   { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
16006   { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
16007   { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
16008   { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
16009   { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
16010   { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
16011   { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
16012   { 0xC00002E1, "STATUS_DS_CANT_START" },
16013   { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
16014   { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
16015   { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
16016   { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
16017   { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
16018   { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
16019   { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
16020   { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
16021   { 0xC0009898, "STATUS_WOW_ASSERTION" },
16022   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
16023   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
16024   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
16025   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
16026   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
16027   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
16028   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
16029   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
16030   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
16031   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
16032   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
16033   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
16034   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
16035   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
16036   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
16037   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
16038   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
16039   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
16040   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
16041   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
16042   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
16043   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
16044   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
16045   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
16046   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
16047   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
16048   { 0xC002001B, "RPC_NT_CALL_FAILED" },
16049   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
16050   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
16051   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
16052   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
16053   { 0xC0020022, "RPC_NT_INVALID_TAG" },
16054   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
16055   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
16056   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
16057   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
16058   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
16059   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
16060   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
16061   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
16062   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
16063   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
16064   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
16065   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
16066   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
16067   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
16068   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
16069   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
16070   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
16071   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
16072   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
16073   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
16074   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
16075   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
16076   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
16077   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
16078   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
16079   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
16080   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
16081   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
16082   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
16083   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
16084   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
16085   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
16086   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
16087   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
16088   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
16089   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
16090   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
16091   { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
16092   { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
16093   { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
16094   { 0xC002100A, "RPC_P_SEND_FAILED" },
16095   { 0xC002100B, "RPC_P_TIMEOUT" },
16096   { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
16097   { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
16098   { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
16099   { 0xC0021015, "RPC_P_THREAD_LISTENING" },
16100   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
16101   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
16102   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
16103   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
16104   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
16105   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
16106   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
16107   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
16108   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
16109   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
16110   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
16111   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
16112   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
16113   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
16114   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
16115   { 0xC002004C, "EPT_NT_CANT_CREATE" },
16116   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
16117   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
16118   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
16119   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
16120   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
16121   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
16122   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
16123   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
16124   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
16125   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
16126   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
16127   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
16128   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
16129   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
16130   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
16131   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
16132   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
16133   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
16134   { 0,          NULL }
16135 };
16136
16137
16138
16139 static const true_false_string tfs_smb_flags_lock = {
16140         "Lock&Read, Write&Unlock are supported",
16141         "Lock&Read, Write&Unlock are not supported"
16142 };
16143 static const true_false_string tfs_smb_flags_receive_buffer = {
16144         "Receive buffer has been posted",
16145         "Receive buffer has not been posted"
16146 };
16147 static const true_false_string tfs_smb_flags_caseless = {
16148         "Path names are caseless",
16149         "Path names are case sensitive"
16150 };
16151 static const true_false_string tfs_smb_flags_canon = {
16152         "Pathnames are canonicalized",
16153         "Pathnames are not canonicalized"
16154 };
16155 static const true_false_string tfs_smb_flags_oplock = {
16156         "OpLock requested/granted",
16157         "OpLock not requested/granted"
16158 };
16159 static const true_false_string tfs_smb_flags_notify = {
16160         "Notify client on all modifications",
16161         "Notify client only on open"
16162 };
16163 static const true_false_string tfs_smb_flags_response = {
16164         "Message is a response to the client/redirector",
16165         "Message is a request to the server"
16166 };
16167
16168 static int
16169 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16170 {
16171         guint8 mask;
16172         proto_item *item = NULL;
16173         proto_tree *tree = NULL;
16174
16175         mask = tvb_get_guint8(tvb, offset);
16176
16177         if(parent_tree){
16178                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
16179                         "Flags: 0x%02x", mask);
16180                 tree = proto_item_add_subtree(item, ett_smb_flags);
16181         }
16182         proto_tree_add_boolean(tree, hf_smb_flags_response,
16183                 tvb, offset, 1, mask);
16184         proto_tree_add_boolean(tree, hf_smb_flags_notify,
16185                 tvb, offset, 1, mask);
16186         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
16187                 tvb, offset, 1, mask);
16188         proto_tree_add_boolean(tree, hf_smb_flags_canon,
16189                 tvb, offset, 1, mask);
16190         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
16191                 tvb, offset, 1, mask);
16192         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
16193                 tvb, offset, 1, mask);
16194         proto_tree_add_boolean(tree, hf_smb_flags_lock,
16195                 tvb, offset, 1, mask);
16196         offset += 1;
16197         return offset;
16198 }
16199
16200
16201
16202 static const true_false_string tfs_smb_flags2_long_names_allowed = {
16203         "Long file names are allowed in the response",
16204         "Long file names are not allowed in the response"
16205 };
16206 static const true_false_string tfs_smb_flags2_ea = {
16207         "Extended attributes are supported",
16208         "Extended attributes are not supported"
16209 };
16210 static const true_false_string tfs_smb_flags2_sec_sig = {
16211         "Security signatures are supported",
16212         "Security signatures are not supported"
16213 };
16214 static const true_false_string tfs_smb_flags2_long_names_used = {
16215         "Path names in request are long file names",
16216         "Path names in request are not long file names"
16217 };
16218 static const true_false_string tfs_smb_flags2_esn = {
16219         "Extended security negotiation is supported",
16220         "Extended security negotiation is not supported"
16221 };
16222 static const true_false_string tfs_smb_flags2_dfs = {
16223         "Resolve pathnames with Dfs",
16224         "Don't resolve pathnames with Dfs"
16225 };
16226 static const true_false_string tfs_smb_flags2_roe = {
16227         "Permit reads if execute-only",
16228         "Don't permit reads if execute-only"
16229 };
16230 static const true_false_string tfs_smb_flags2_nt_error = {
16231         "Error codes are NT error codes",
16232         "Error codes are DOS error codes"
16233 };
16234 static const true_false_string tfs_smb_flags2_string = {
16235         "Strings are Unicode",
16236         "Strings are ASCII"
16237 };
16238 static int
16239 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16240 {
16241         guint16 mask;
16242         proto_item *item = NULL;
16243         proto_tree *tree = NULL;
16244
16245         mask = tvb_get_letohs(tvb, offset);
16246
16247         if(parent_tree){
16248                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
16249                         "Flags2: 0x%04x", mask);
16250                 tree = proto_item_add_subtree(item, ett_smb_flags2);
16251         }
16252
16253         proto_tree_add_boolean(tree, hf_smb_flags2_string,
16254                 tvb, offset, 2, mask);
16255         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
16256                 tvb, offset, 2, mask);
16257         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
16258                 tvb, offset, 2, mask);
16259         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
16260                 tvb, offset, 2, mask);
16261         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
16262                 tvb, offset, 2, mask);
16263         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
16264                 tvb, offset, 2, mask);
16265         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
16266                 tvb, offset, 2, mask);
16267         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
16268                 tvb, offset, 2, mask);
16269         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
16270                 tvb, offset, 2, mask);
16271
16272         offset += 2;
16273         return offset;
16274 }
16275
16276
16277
16278 #define SMB_FLAGS_DIRN 0x80
16279
16280
16281 static void
16282 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16283 {
16284         int offset = 0;
16285         proto_item *item = NULL, *hitem = NULL;
16286         proto_tree *tree = NULL, *htree = NULL;
16287         guint8          flags;
16288         guint16         flags2;
16289         static smb_info_t       si_arr[20];
16290         static int si_counter=0;
16291         smb_info_t              *si;
16292         smb_saved_info_t *sip = NULL;
16293         smb_saved_info_key_t key;
16294         smb_saved_info_key_t *new_key;
16295         guint32 nt_status = 0;
16296         guint8 errclass = 0;
16297         guint16 errcode = 0;
16298         guint32 pid_mid;
16299         conversation_t *conversation;
16300         nstime_t ns;
16301
16302         si_counter++;
16303         if(si_counter==20){
16304                 si_counter=0;
16305         }
16306         si=&si_arr[si_counter];
16307
16308         top_tree=parent_tree;
16309
16310         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
16311                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
16312         }
16313         if (check_col(pinfo->cinfo, COL_INFO)){
16314                 col_clear(pinfo->cinfo, COL_INFO);
16315         }
16316
16317         /* start off using the local variable, we will allocate a new one if we
16318            need to*/
16319         si->cmd = tvb_get_guint8(tvb, offset+4);
16320         flags = tvb_get_guint8(tvb, offset+9);
16321         /*
16322          * XXX - in some SMB-over-OSI-transport and SMB-over-Vines traffic,
16323          * the direction flag appears never to be set, even for what appear
16324          * to be replies.  Do some SMB servers fail to set that flag,
16325          * under the assumption that the client knows it's a reply because
16326          * it received it?
16327          */
16328         si->request = !(flags&SMB_FLAGS_DIRN);
16329         flags2 = tvb_get_letohs(tvb, offset+10);
16330         if(flags2 & 0x8000){
16331                 si->unicode = TRUE; /* Mark them as Unicode */
16332         } else {
16333                 si->unicode = FALSE;
16334         }
16335         si->tid = tvb_get_letohs(tvb, offset+24);
16336         si->pid = tvb_get_letohs(tvb, offset+26);
16337         si->uid = tvb_get_letohs(tvb, offset+28);
16338         si->mid = tvb_get_letohs(tvb, offset+30);
16339         pid_mid = (si->pid << 16) | si->mid;
16340         si->info_level = -1;
16341         si->info_count = -1;
16342
16343         if (parent_tree) {
16344                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
16345                         -1, FALSE);
16346                 tree = proto_item_add_subtree(item, ett_smb);
16347
16348                 hitem = proto_tree_add_text(tree, tvb, offset, 32,
16349                         "SMB Header");
16350
16351                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
16352         }
16353
16354         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
16355         offset += 4;  /* Skip the marker */
16356
16357         /* find which conversation we are part of and get the tables for that
16358            conversation*/
16359         conversation = find_conversation(&pinfo->src, &pinfo->dst,
16360                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
16361         if(!conversation){
16362                 /* OK this is a new conversation so lets create it */
16363                 conversation = conversation_new(&pinfo->src, &pinfo->dst,
16364                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
16365         }
16366         /* see if we already have the smb data for this conversation */
16367         si->ct=conversation_get_proto_data(conversation, proto_smb);
16368         if(!si->ct){
16369                 /* No, not yet. create it and attach it to the conversation */
16370                 si->ct = g_mem_chunk_alloc(conv_tables_chunk);
16371                 conv_tables = g_slist_prepend(conv_tables, si->ct);
16372                 si->ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
16373                         smb_saved_info_equal_matched);
16374                 si->ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
16375                         smb_saved_info_equal_unmatched);
16376                 si->ct->tid_service=g_hash_table_new(
16377                         smb_saved_info_hash_unmatched,
16378                         smb_saved_info_equal_unmatched);
16379                 conversation_add_proto_data(conversation, proto_smb, si->ct);
16380         }
16381
16382         if( (si->request)
16383             &&  (si->mid==0)
16384             &&  (si->uid==0)
16385             &&  (si->pid==0)
16386             &&  (si->tid==0) ){
16387                 /* this is a broadcast SMB packet, there will not be a reply.
16388                    We dont need to do anything
16389                 */
16390                 si->unidir = TRUE;
16391         } else if( (si->cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
16392                    ||(si->cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
16393                    ||(si->cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
16394                    ||(si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
16395                 /* Ok, we got a special request type. This request is either
16396                    an NT Cancel or a continuation relative to a real request
16397                    in an earlier packet.  In either case, we don't expect any
16398                    responses to this packet.  For continuations, any later
16399                    responses we see really just belong to the original request.
16400                    Anyway, we want to remember this packet somehow and
16401                    remember which original request it is associated with so
16402                    we can say nice things such as "This is a Cancellation to
16403                    the request in frame x", but we don't want the
16404                    request/response matching to get messed up.
16405
16406                    The only thing we do in this case is trying to find which original
16407                    request we match with and insert an entry for this "special"
16408                    request for later reference. We continue to reference the original
16409                    requests smb_saved_info_t but we dont touch it or change anything
16410                    in it.
16411                 */
16412
16413                 si->unidir = TRUE;  /*we dont expect an answer to this one*/
16414
16415                 if(!pinfo->fd->flags.visited){
16416                         /* try to find which original call we match and if we
16417                            find it add us to the matched table. Dont touch
16418                            anything else since we dont want this one to mess
16419                            up the request/response matching. We still consider
16420                            the initial call the real request and this is only
16421                            some sort of continuation.
16422                         */
16423                         /* we only check the unmatched table and assume that the
16424                            last seen MID matching ours is the right one.
16425                            This can fail but is better than nothing
16426                         */
16427                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
16428                         if(sip!=NULL){
16429                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16430                                 new_key->frame = pinfo->fd->num;
16431                                 new_key->pid_mid = pid_mid;
16432                                 g_hash_table_insert(si->ct->matched, new_key,
16433                                     sip);
16434                         }
16435                 } else {
16436                         /* we have seen this packet before; check the
16437                            matching table
16438                         */
16439                         key.frame = pinfo->fd->num;
16440                         key.pid_mid = pid_mid;
16441                         sip=g_hash_table_lookup(si->ct->matched, &key);
16442                         if(sip==NULL){
16443                         /*
16444                           We didn't find it.
16445                           Too bad, unfortunately there is not really much we can
16446                           do now since this means that we never saw the initial
16447                           request.
16448                          */
16449                         }
16450                 }
16451
16452
16453                 if(sip && sip->frame_req){
16454                         switch(si->cmd){
16455                         case SMB_COM_NT_CANCEL:
16456                                 proto_tree_add_uint(htree, hf_smb_cancel_to,
16457                                                     tvb, 0, 0, sip->frame_req);
16458                                 break;
16459                         case SMB_COM_TRANSACTION_SECONDARY:
16460                         case SMB_COM_TRANSACTION2_SECONDARY:
16461                         case SMB_COM_NT_TRANSACT_SECONDARY:
16462                                 proto_tree_add_uint(htree, hf_smb_continuation_to,
16463                                                     tvb, 0, 0, sip->frame_req);
16464                                 break;
16465                         }
16466                 } else {
16467                         switch(si->cmd){
16468                         case SMB_COM_NT_CANCEL:
16469                                 proto_tree_add_text(htree, tvb, 0, 0,
16470                                                     "Cancellation to: <unknown frame>");
16471                                 break;
16472                         case SMB_COM_TRANSACTION_SECONDARY:
16473                         case SMB_COM_TRANSACTION2_SECONDARY:
16474                         case SMB_COM_NT_TRANSACT_SECONDARY:
16475                                 proto_tree_add_text(htree, tvb, 0, 0,
16476                                                     "Continuation to: <unknown frame>");
16477                                 break;
16478                         }
16479                 }
16480         } else { /* normal bidirectional request or response */
16481                 si->unidir = FALSE;
16482
16483                 if(!pinfo->fd->flags.visited){
16484                         /* first see if we find an unmatched smb "equal" to
16485                            the current one
16486                         */
16487                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
16488                         if(sip!=NULL){
16489                                 gboolean cmd_match=FALSE;
16490
16491                                 /*
16492                                  * Make sure the SMB we found was the
16493                                  * same command, or a different command
16494                                  * that's another valid type of reply
16495                                  * to that command.
16496                                  */
16497                                 if(si->cmd==sip->cmd){
16498                                         cmd_match=TRUE;
16499                                 }
16500                                 else if(si->cmd==SMB_COM_NT_CANCEL){
16501                                         cmd_match=TRUE;
16502                                 }
16503                                 else if((si->cmd==SMB_COM_TRANSACTION_SECONDARY)
16504                                      && (sip->cmd==SMB_COM_TRANSACTION)){
16505                                         cmd_match=TRUE;
16506                                 }
16507                                 else if((si->cmd==SMB_COM_TRANSACTION2_SECONDARY)
16508                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
16509                                         cmd_match=TRUE;
16510                                 }
16511                                 else if((si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)
16512                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
16513                                         cmd_match=TRUE;
16514                                 }
16515
16516                                 if( (si->request) || (!cmd_match) ) {
16517                                         /* If we are processing an SMB request but there was already
16518                                            another "identical" smb resuest we had not matched yet.
16519                                            This must mean that either we have a retransmission or that the
16520                                            response to the previous one was lost and the client has reused
16521                                            the MID for this conversation. In either case it's not much more
16522                                            we can do than forget the old request and concentrate on the
16523                                            present one instead.
16524
16525                                            We also do this cleanup if we see that the cmd in the original
16526                                            request in sip->cmd is not compatible with the current cmd.
16527                                            This is to prevent matching errors such as if there were two
16528                                            SMBs of different cmds but with identical MID and PID values and
16529                                            if ethereal lost the first reply and the second request.
16530                                         */
16531                                         g_hash_table_remove(si->ct->unmatched, (void *)pid_mid);
16532                                         sip=NULL; /* XXX should free it as well */
16533                                 } else {
16534                                         /* we have found a response to some request we have seen earlier.
16535                                            What we do now depends on whether this is the first response
16536                                            to that request we see (id frame_res==0) or not.
16537                                         */
16538                                         if(sip->frame_res==0){
16539                                                 /* ok it is the first response we have seen to this packet */
16540                                                 sip->frame_res = pinfo->fd->num;
16541                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16542                                                 new_key->frame = sip->frame_res;
16543                                                 new_key->pid_mid = pid_mid;
16544                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16545                                         } else {
16546                                                 /* We have already seen another response to this MID.
16547                                                    Since the MID in reality is only something like 10 bits
16548                                                    this probably means that we just have a MID that is being
16549                                                    reused due to the small MID space and that this is a new
16550                                                    command we did not see the original request for.
16551                                                 */
16552                                                 sip=NULL;
16553                                         }
16554                                 }
16555                         }
16556                         if(si->request){
16557                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
16558                                 sip->frame_req = pinfo->fd->num;
16559                                 sip->frame_res = 0;
16560                                 sip->req_time.secs=pinfo->fd->abs_secs;
16561                                 sip->req_time.nsecs=pinfo->fd->abs_usecs*1000;
16562                                 sip->flags = 0;
16563                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)
16564                                     == (void *)TID_IPC) {
16565                                         sip->flags |= SMB_SIF_TID_IS_IPC;
16566                                 }
16567                                 sip->cmd = si->cmd;
16568                                 sip->extra_info = NULL;
16569                                 g_hash_table_insert(si->ct->unmatched, (void *)pid_mid, sip);
16570                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16571                                 new_key->frame = sip->frame_req;
16572                                 new_key->pid_mid = pid_mid;
16573                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16574                         }
16575                 } else {
16576                         /* we have seen this packet before; check the
16577                            matching table.
16578                            If we haven't yet seen the reply, we won't
16579                            find the info for it; we don't need it, as
16580                            we only use it to save information, and, as
16581                            we've seen this packet before, we've already
16582                            saved the information.
16583                         */
16584                         key.frame = pinfo->fd->num;
16585                         key.pid_mid = pid_mid;
16586                         sip=g_hash_table_lookup(si->ct->matched, &key);
16587                 }
16588         }
16589
16590         /*
16591          * Pass the "sip" on to subdissectors through "si".
16592          */
16593         si->sip = sip;
16594
16595         if (sip != NULL) {
16596                 /*
16597                  * Put in fields for the frame number of the frame to which
16598                  * this is a response or the frame with the response to this
16599                  * frame - if we know the frame number (i.e., it's not 0).
16600                  */
16601                 if(si->request){
16602                         if (sip->frame_res != 0)
16603                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
16604                 } else {
16605                         if (sip->frame_req != 0) {
16606                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
16607                                 ns.secs = pinfo->fd->abs_secs - sip->req_time.secs;
16608                                 ns.nsecs = pinfo->fd->abs_usecs*1000 - sip->req_time.nsecs;
16609                                 if(ns.nsecs<0){
16610                                         ns.nsecs+=1000000000;
16611                                         ns.secs--;
16612                                 }
16613                                 proto_tree_add_time(htree, hf_smb_time, tvb,
16614                                     0, 0, &ns);
16615                         }
16616                 }
16617         }
16618
16619         /* smb command */
16620         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);
16621         offset += 1;
16622
16623         if(flags2 & 0x4000){
16624                 /* handle NT 32 bit error code */
16625
16626                 nt_status = tvb_get_letohl(tvb, offset);
16627
16628                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
16629                         TRUE);
16630                 offset += 4;
16631
16632         } else {
16633                 /* handle DOS error code & class */
16634                 errclass = tvb_get_guint8(tvb, offset);
16635                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
16636                         errclass);
16637                 offset += 1;
16638
16639                 /* reserved byte */
16640                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
16641                 offset += 1;
16642
16643                 /* error code */
16644                 /* XXX - the type of this field depends on the value of
16645                  * "errcls", so there is isn't a single value_string array
16646                  * fo it, so there can't be a single field for it.
16647                  */
16648                 errcode = tvb_get_letohs(tvb, offset);
16649                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
16650                         offset, 2, errcode, "Error Code: %s",
16651                         decode_smb_error(errclass, errcode));
16652                 offset += 2;
16653         }
16654
16655         /* flags */
16656         offset = dissect_smb_flags(tvb, htree, offset);
16657
16658         /* flags2 */
16659         offset = dissect_smb_flags2(tvb, htree, offset);
16660
16661         /*
16662          * The document at
16663          *
16664          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
16665          *
16666          * (a text version of "Microsoft Networks SMB FILE SHARING
16667          * PROTOCOL, Document Version 6.0p") says that:
16668          *
16669          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
16670          *      the "High Part of PID";
16671          *
16672          *      the next four bytes are reserved;
16673          *
16674          *      the next four bytes are, for SMB-over-IPX (with no
16675          *      NetBIOS involved) two bytes of Session ID and two bytes
16676          *      of SequenceNumber.
16677          *
16678          * Network Monitor 2.x dissects the four bytes before the Session ID
16679          * as a "Key", and the two bytes after the SequenceNumber as
16680          * a "Group ID".
16681          *
16682          * The "High Part of PID" has been seen in calls other than NT
16683          * Create and X, although most of them appear to be I/O on DCE RPC
16684          * pipes opened with the NT Create and X in question.
16685          */
16686         proto_tree_add_item(htree, hf_smb_pid_high, tvb, offset, 2, TRUE);
16687         offset += 2;
16688
16689         if (pinfo->ptype == PT_IPX &&
16690             (pinfo->match_port == IPX_SOCKET_NWLINK_SMB_SERVER ||
16691              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_REDIR ||
16692              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_MESSENGER)) {
16693                 /*
16694                  * This is SMB-over-IPX.
16695                  * XXX - do we have to worry about "sequenced commands",
16696                  * as per the Samba document?  They say that for
16697                  * "unsequenced commands" (with a sequence number of 0),
16698                  * the Mid must be unique, but perhaps the Mid doesn't
16699                  * have to be unique for sequenced commands.  In at least
16700                  * one capture with SMB-over-IPX, however, the Mids
16701                  * are unique even for sequenced commands.
16702                  */
16703                 /* Key */
16704                 proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
16705                     TRUE);
16706                 offset += 4;
16707
16708                 /* Session ID */
16709                 proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
16710                     TRUE);
16711                 offset += 2;
16712
16713                 /* Sequence number */
16714                 proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
16715                     TRUE);
16716                 offset += 2;
16717
16718                 /* Group ID */
16719                 proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
16720                     TRUE);
16721                 offset += 2;
16722         } else {
16723                 /*
16724                  * According to http://ubiqx.org/cifs/SMB.html#SMB.4.2.1
16725                  * and http://ubiqx.org/cifs/SMB.html#SMB.5.5.1 the 8
16726                  * bytes after the "High part of PID" are an 8-byte
16727                  * signature ...
16728                  */
16729                 proto_tree_add_item(htree, hf_smb_sig, tvb, offset, 8, TRUE);
16730                 offset += 8;
16731
16732                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2, TRUE);
16733                 offset += 2;
16734         }
16735
16736         /* TID */
16737         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si->tid);
16738         offset += 2;
16739
16740         /* PID */
16741         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
16742         offset += 2;
16743
16744         /* UID */
16745         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si->uid);
16746         offset += 2;
16747
16748         /* MID */
16749         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
16750         offset += 2;
16751
16752         pinfo->private_data = si;
16753
16754         /* tap the packet before the dissectors are called so we still get
16755            the tap listener called even if there is an exception.
16756         */
16757         tap_queue_packet(smb_tap, pinfo, si);
16758         dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE);
16759
16760         /* Append error info from this packet to info string. */
16761         if (!si->request && check_col(pinfo->cinfo, COL_INFO)) {
16762                 if (flags2 & 0x4000) {
16763                         /*
16764                          * The status is an NT status code; was there
16765                          * an error?
16766                          */
16767                         if ((nt_status & 0xC0000000) == 0xC0000000) {
16768                                 /*
16769                                  * Yes.
16770                                  */
16771                                 col_append_fstr(
16772                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16773                                         val_to_str(nt_status, NT_errors,
16774                                             "Unknown (0x%08X)"));
16775                         }
16776                 } else {
16777                         /*
16778                          * The status is a DOS error class and code; was
16779                          * there an error?
16780                          */
16781                         if (errclass != SMB_SUCCESS) {
16782                                 /*
16783                                  * Yes.
16784                                  */
16785                                 col_append_fstr(
16786                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16787                                         decode_smb_error(errclass, errcode));
16788                         }
16789                 }
16790         }
16791 }
16792
16793 static gboolean
16794 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16795 {
16796         /* must check that this really is a smb packet */
16797         if (!tvb_bytes_exist(tvb, 0, 4))
16798                 return FALSE;
16799
16800         if( (tvb_get_guint8(tvb, 0) != 0xff)
16801             || (tvb_get_guint8(tvb, 1) != 'S')
16802             || (tvb_get_guint8(tvb, 2) != 'M')
16803             || (tvb_get_guint8(tvb, 3) != 'B') ){
16804                 return FALSE;
16805         }
16806
16807         dissect_smb(tvb, pinfo, parent_tree);
16808         return TRUE;
16809 }
16810
16811 void
16812 proto_register_smb(void)
16813 {
16814         static hf_register_info hf[] = {
16815         { &hf_smb_cmd,
16816                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
16817                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
16818
16819         { &hf_smb_word_count,
16820                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
16821                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
16822
16823         { &hf_smb_byte_count,
16824                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
16825                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
16826
16827         { &hf_smb_response_to,
16828                 { "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
16829                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
16830
16831         { &hf_smb_time,
16832                 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
16833                 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
16834
16835         { &hf_smb_response_in,
16836                 { "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
16837                 NULL, 0, "The response to this packet is in this packet", HFILL }},
16838
16839         { &hf_smb_continuation_to,
16840                 { "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
16841                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
16842
16843         { &hf_smb_nt_status,
16844                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
16845                 VALS(NT_errors), 0, "NT Status code", HFILL }},
16846
16847         { &hf_smb_error_class,
16848                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
16849                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
16850
16851         { &hf_smb_error_code,
16852                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
16853                 NULL, 0, "DOS Error Code", HFILL }},
16854
16855         { &hf_smb_reserved,
16856                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
16857                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
16858
16859         { &hf_smb_sig,
16860                 { "Signature", "smb.signature", FT_BYTES, BASE_HEX,
16861                 NULL, 0, "Signature bytes", HFILL }},
16862
16863         { &hf_smb_key,
16864                 { "Key", "smb.key", FT_UINT32, BASE_HEX,
16865                 NULL, 0, "SMB-over-IPX Key", HFILL }},
16866
16867         { &hf_smb_session_id,
16868                 { "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
16869                 NULL, 0, "SMB-over-IPX Session ID", HFILL }},
16870
16871         { &hf_smb_sequence_num,
16872                 { "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
16873                 NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
16874
16875         { &hf_smb_group_id,
16876                 { "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
16877                 NULL, 0, "SMB-over-IPX Group ID", HFILL }},
16878
16879         { &hf_smb_pid,
16880                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
16881                 NULL, 0, "Process ID", HFILL }},
16882
16883         { &hf_smb_pid_high,
16884                 { "Process ID High", "smb.pid.high", FT_UINT16, BASE_DEC,
16885                 NULL, 0, "Process ID High Bytes", HFILL }},
16886
16887         { &hf_smb_tid,
16888                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
16889                 NULL, 0, "Tree ID", HFILL }},
16890
16891         { &hf_smb_uid,
16892                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
16893                 NULL, 0, "User ID", HFILL }},
16894
16895         { &hf_smb_mid,
16896                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
16897                 NULL, 0, "Multiplex ID", HFILL }},
16898
16899         { &hf_smb_flags_lock,
16900                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
16901                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
16902
16903         { &hf_smb_flags_receive_buffer,
16904                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
16905                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
16906
16907         { &hf_smb_flags_caseless,
16908                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
16909                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
16910
16911         { &hf_smb_flags_canon,
16912                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
16913                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
16914
16915         { &hf_smb_flags_oplock,
16916                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
16917                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
16918
16919         { &hf_smb_flags_notify,
16920                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
16921                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
16922
16923         { &hf_smb_flags_response,
16924                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
16925                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
16926
16927         { &hf_smb_flags2_long_names_allowed,
16928                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
16929                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
16930
16931         { &hf_smb_flags2_ea,
16932                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
16933                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
16934
16935         { &hf_smb_flags2_sec_sig,
16936                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
16937                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
16938
16939         { &hf_smb_flags2_long_names_used,
16940                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
16941                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
16942
16943         { &hf_smb_flags2_esn,
16944                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
16945                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
16946
16947         { &hf_smb_flags2_dfs,
16948                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
16949                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
16950
16951         { &hf_smb_flags2_roe,
16952                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
16953                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
16954
16955         { &hf_smb_flags2_nt_error,
16956                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
16957                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
16958
16959         { &hf_smb_flags2_string,
16960                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
16961                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
16962
16963         { &hf_smb_buffer_format,
16964                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
16965                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
16966
16967         { &hf_smb_dialect_name,
16968                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
16969                 NULL, 0, "Name of dialect", HFILL }},
16970
16971         { &hf_smb_dialect_index,
16972                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
16973                 NULL, 0, "Index of selected dialect", HFILL }},
16974
16975         { &hf_smb_max_trans_buf_size,
16976                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
16977                 NULL, 0, "Maximum transmit buffer size", HFILL }},
16978
16979         { &hf_smb_max_mpx_count,
16980                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
16981                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
16982
16983         { &hf_smb_max_vcs_num,
16984                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
16985                 NULL, 0, "Maximum VCs between client and server", HFILL }},
16986
16987         { &hf_smb_session_key,
16988                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
16989                 NULL, 0, "Unique token identifying this session", HFILL }},
16990
16991         { &hf_smb_server_timezone,
16992                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
16993                 NULL, 0, "Current timezone at server.", HFILL }},
16994
16995         { &hf_smb_encryption_key_length,
16996                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
16997                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
16998
16999         { &hf_smb_encryption_key,
17000                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
17001                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
17002
17003         { &hf_smb_primary_domain,
17004                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
17005                 NULL, 0, "The server's primary domain", HFILL }},
17006
17007         { &hf_smb_server,
17008                 { "Server", "smb.server", FT_STRING, BASE_NONE,
17009                 NULL, 0, "The name of the DC/server", HFILL }},
17010
17011         { &hf_smb_max_raw_buf_size,
17012                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
17013                 NULL, 0, "Maximum raw buffer size", HFILL }},
17014
17015         { &hf_smb_server_guid,
17016                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
17017                 NULL, 0, "Globally unique identifier for this server", HFILL }},
17018
17019         { &hf_smb_security_blob_len,
17020                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
17021                 NULL, 0, "Security blob length", HFILL }},
17022
17023         { &hf_smb_security_blob,
17024                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
17025                 NULL, 0, "Security blob", HFILL }},
17026
17027         { &hf_smb_sm_mode16,
17028                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
17029                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
17030
17031         { &hf_smb_sm_password16,
17032                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
17033                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
17034
17035         { &hf_smb_sm_mode,
17036                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
17037                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
17038
17039         { &hf_smb_sm_password,
17040                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
17041                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
17042
17043         { &hf_smb_sm_signatures,
17044                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
17045                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
17046
17047         { &hf_smb_sm_sig_required,
17048                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
17049                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
17050
17051         { &hf_smb_rm_read,
17052                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
17053                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
17054
17055         { &hf_smb_rm_write,
17056                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
17057                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
17058
17059         { &hf_smb_server_date_time,
17060                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
17061                 NULL, 0, "Current date and time at server", HFILL }},
17062
17063         { &hf_smb_server_smb_date,
17064                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
17065                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
17066
17067         { &hf_smb_server_smb_time,
17068                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
17069                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
17070
17071         { &hf_smb_server_cap_raw_mode,
17072                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
17073                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
17074
17075         { &hf_smb_server_cap_mpx_mode,
17076                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
17077                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
17078
17079         { &hf_smb_server_cap_unicode,
17080                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
17081                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
17082
17083         { &hf_smb_server_cap_large_files,
17084                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
17085                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
17086
17087         { &hf_smb_server_cap_nt_smbs,
17088                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
17089                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
17090
17091         { &hf_smb_server_cap_rpc_remote_apis,
17092                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
17093                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
17094
17095         { &hf_smb_server_cap_nt_status,
17096                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
17097                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
17098
17099         { &hf_smb_server_cap_level_ii_oplocks,
17100                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
17101                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
17102
17103         { &hf_smb_server_cap_lock_and_read,
17104                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
17105                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
17106
17107         { &hf_smb_server_cap_nt_find,
17108                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
17109                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
17110
17111         { &hf_smb_server_cap_dfs,
17112                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
17113                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
17114
17115         { &hf_smb_server_cap_infolevel_passthru,
17116                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
17117                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
17118
17119         { &hf_smb_server_cap_large_readx,
17120                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
17121                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
17122
17123         { &hf_smb_server_cap_large_writex,
17124                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
17125                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
17126
17127         { &hf_smb_server_cap_unix,
17128                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
17129                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
17130
17131         { &hf_smb_server_cap_reserved,
17132                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
17133                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
17134
17135         { &hf_smb_server_cap_bulk_transfer,
17136                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
17137                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
17138
17139         { &hf_smb_server_cap_compressed_data,
17140                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
17141                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
17142
17143         { &hf_smb_server_cap_extended_security,
17144                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
17145                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
17146
17147         { &hf_smb_system_time,
17148                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
17149                 NULL, 0, "System Time", HFILL }},
17150
17151         { &hf_smb_unknown,
17152                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
17153                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
17154
17155         { &hf_smb_dir_name,
17156                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
17157                 NULL, 0, "SMB Directory Name", HFILL }},
17158
17159         { &hf_smb_echo_count,
17160                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
17161                 NULL, 0, "Number of times to echo data back", HFILL }},
17162
17163         { &hf_smb_echo_data,
17164                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
17165                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
17166
17167         { &hf_smb_echo_seq_num,
17168                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
17169                 NULL, 0, "Sequence number for this echo response", HFILL }},
17170
17171         { &hf_smb_max_buf_size,
17172                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
17173                 NULL, 0, "Max client buffer size", HFILL }},
17174
17175         { &hf_smb_path,
17176                 { "Path", "smb.path", FT_STRING, BASE_NONE,
17177                 NULL, 0, "Path. Server name and share name", HFILL }},
17178
17179         { &hf_smb_service,
17180                 { "Service", "smb.service", FT_STRING, BASE_NONE,
17181                 NULL, 0, "Service name", HFILL }},
17182
17183         { &hf_smb_password,
17184                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
17185                 NULL, 0, "Password", HFILL }},
17186
17187         { &hf_smb_ansi_password,
17188                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
17189                 NULL, 0, "ANSI Password", HFILL }},
17190
17191         { &hf_smb_unicode_password,
17192                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
17193                 NULL, 0, "Unicode Password", HFILL }},
17194
17195         { &hf_smb_move_flags_file,
17196                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
17197                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17198
17199         { &hf_smb_move_flags_dir,
17200                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
17201                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17202
17203         { &hf_smb_move_flags_verify,
17204                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
17205                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17206
17207         { &hf_smb_files_moved,
17208                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
17209                 NULL, 0, "Number of files moved", HFILL }},
17210
17211         { &hf_smb_copy_flags_file,
17212                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
17213                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17214
17215         { &hf_smb_copy_flags_dir,
17216                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
17217                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17218
17219         { &hf_smb_copy_flags_dest_mode,
17220                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
17221                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
17222
17223         { &hf_smb_copy_flags_source_mode,
17224                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
17225                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
17226
17227         { &hf_smb_copy_flags_verify,
17228                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
17229                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17230
17231         { &hf_smb_copy_flags_tree_copy,
17232                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
17233                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
17234
17235         { &hf_smb_copy_flags_ea_action,
17236                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
17237                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
17238
17239         { &hf_smb_count,
17240                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
17241                 NULL, 0, "Count number of items/bytes", HFILL }},
17242
17243         { &hf_smb_count_low,
17244                 { "Count Low", "smb.count_low", FT_UINT16, BASE_DEC,
17245                 NULL, 0, "Count number of items/bytes, Low 16 bits", HFILL }},
17246
17247         { &hf_smb_count_high,
17248                 { "Count High (multiply with 64K)", "smb.count_high", FT_UINT16, BASE_DEC,
17249                 NULL, 0, "Count number of items/bytes, High 16 bits", HFILL }},
17250
17251         { &hf_smb_file_name,
17252                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
17253                 NULL, 0, "File Name", HFILL }},
17254
17255         { &hf_smb_open_function_create,
17256                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
17257                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
17258
17259         { &hf_smb_open_function_open,
17260                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
17261                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
17262
17263         { &hf_smb_fid,
17264                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
17265                 NULL, 0, "FID: File ID", HFILL }},
17266
17267         { &hf_smb_file_attr_read_only_16bit,
17268                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
17269                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17270
17271         { &hf_smb_file_attr_read_only_8bit,
17272                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
17273                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17274
17275         { &hf_smb_file_attr_hidden_16bit,
17276                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
17277                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17278
17279         { &hf_smb_file_attr_hidden_8bit,
17280                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
17281                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17282
17283         { &hf_smb_file_attr_system_16bit,
17284                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
17285                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17286
17287         { &hf_smb_file_attr_system_8bit,
17288                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
17289                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17290
17291         { &hf_smb_file_attr_volume_16bit,
17292                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
17293                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
17294
17295         { &hf_smb_file_attr_volume_8bit,
17296                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
17297                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
17298
17299         { &hf_smb_file_attr_directory_16bit,
17300                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
17301                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17302
17303         { &hf_smb_file_attr_directory_8bit,
17304                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
17305                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17306
17307         { &hf_smb_file_attr_archive_16bit,
17308                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
17309                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17310
17311         { &hf_smb_file_attr_archive_8bit,
17312                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
17313                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17314
17315         { &hf_smb_file_attr_device,
17316                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
17317                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
17318
17319         { &hf_smb_file_attr_normal,
17320                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
17321                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
17322
17323         { &hf_smb_file_attr_temporary,
17324                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
17325                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
17326
17327         { &hf_smb_file_attr_sparse,
17328                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
17329                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
17330
17331         { &hf_smb_file_attr_reparse,
17332                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
17333                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
17334
17335         { &hf_smb_file_attr_compressed,
17336                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
17337                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
17338
17339         { &hf_smb_file_attr_offline,
17340                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
17341                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
17342
17343         { &hf_smb_file_attr_not_content_indexed,
17344                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
17345                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
17346
17347         { &hf_smb_file_attr_encrypted,
17348                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
17349                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
17350
17351         { &hf_smb_file_size,
17352                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
17353                 NULL, 0, "File Size", HFILL }},
17354
17355         { &hf_smb_search_attribute_read_only,
17356                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
17357                 TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
17358
17359         { &hf_smb_search_attribute_hidden,
17360                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
17361                 TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
17362
17363         { &hf_smb_search_attribute_system,
17364                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
17365                 TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
17366
17367         { &hf_smb_search_attribute_volume,
17368                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
17369                 TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
17370
17371         { &hf_smb_search_attribute_directory,
17372                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
17373                 TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
17374
17375         { &hf_smb_search_attribute_archive,
17376                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
17377                 TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
17378
17379         { &hf_smb_access_mode,
17380                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
17381                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
17382
17383         { &hf_smb_access_sharing,
17384                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
17385                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
17386
17387         { &hf_smb_access_locality,
17388                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
17389                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
17390
17391         { &hf_smb_access_caching,
17392                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
17393                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
17394
17395         { &hf_smb_access_writetru,
17396                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
17397                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
17398
17399         { &hf_smb_create_time,
17400                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
17401                 NULL, 0, "Creation Time", HFILL }},
17402
17403         { &hf_smb_modify_time,
17404                 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
17405                   NULL, 0, "Modification Time", HFILL }},
17406
17407         { &hf_smb_backup_time,
17408                 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
17409                   NULL, 0, "Backup time", HFILL}},
17410
17411         { &hf_smb_mac_alloc_block_count,
17412                 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
17413                   NULL, 0, "Allocation Block Count", HFILL}},
17414
17415         { &hf_smb_mac_alloc_block_size,
17416                 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
17417                   NULL, 0, "Allocation Block Size", HFILL}},
17418
17419         { &hf_smb_mac_free_block_count,
17420                 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
17421                   NULL, 0, "Free Block Count", HFILL}},
17422
17423         { &hf_smb_mac_root_file_count,
17424                 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
17425                 NULL, 0, "Root File Count", HFILL}},
17426
17427         { &hf_smb_mac_root_dir_count,
17428           { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
17429             NULL, 0, "Root Directory Count", HFILL}},
17430
17431         { &hf_smb_mac_file_count,
17432           { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
17433             NULL, 0, "File Count", HFILL}},
17434
17435         { &hf_smb_mac_dir_count,
17436           { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
17437             NULL, 0, "Directory Count", HFILL}},
17438
17439         { &hf_smb_mac_support_flags,
17440           { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
17441             NULL, 0, "Mac Support Flags", HFILL}},
17442
17443         { &hf_smb_mac_sup_access_ctrl,
17444           { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
17445             TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
17446
17447         { &hf_smb_mac_sup_getset_comments,
17448           { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
17449             TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
17450
17451         { &hf_smb_mac_sup_desktopdb_calls,
17452           { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
17453             TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
17454
17455         { &hf_smb_mac_sup_unique_ids,
17456           { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
17457             TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
17458
17459         { &hf_smb_mac_sup_streams,
17460           { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
17461             TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
17462
17463         { &hf_smb_create_dos_date,
17464                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
17465                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
17466
17467         { &hf_smb_create_dos_time,
17468                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
17469                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
17470
17471         { &hf_smb_last_write_time,
17472                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
17473                 NULL, 0, "Time this file was last written to", HFILL }},
17474
17475         { &hf_smb_last_write_dos_date,
17476                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
17477                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
17478
17479         { &hf_smb_last_write_dos_time,
17480                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
17481                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
17482
17483         { &hf_smb_old_file_name,
17484                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
17485                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
17486
17487         { &hf_smb_offset,
17488                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
17489                 NULL, 0, "Offset in file", HFILL }},
17490
17491         { &hf_smb_remaining,
17492                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
17493                 NULL, 0, "Remaining number of bytes", HFILL }},
17494
17495         { &hf_smb_padding,
17496                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
17497                 NULL, 0, "Padding or unknown data", HFILL }},
17498
17499         { &hf_smb_file_data,
17500                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
17501                 NULL, 0, "Data read/written to the file", HFILL }},
17502
17503         { &hf_smb_mac_fndrinfo,
17504                 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_HEX,
17505                   NULL, 0, "Finder Info", HFILL}},
17506
17507         { &hf_smb_total_data_len,
17508                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
17509                 NULL, 0, "Total length of data", HFILL }},
17510
17511         { &hf_smb_data_len,
17512                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
17513                 NULL, 0, "Length of data", HFILL }},
17514
17515         { &hf_smb_data_len_low,
17516                 { "Data Length Low", "smb.data_len_low", FT_UINT16, BASE_DEC,
17517                 NULL, 0, "Length of data, Low 16 bits", HFILL }},
17518
17519         { &hf_smb_data_len_high,
17520                 { "Data Length High (multiply with 64K)", "smb.data_len_high", FT_UINT16, BASE_DEC,
17521                 NULL, 0, "Length of data, High 16 bits", HFILL }},
17522
17523         { &hf_smb_seek_mode,
17524                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
17525                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
17526
17527         { &hf_smb_access_time,
17528                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
17529                 NULL, 0, "Last Access Time", HFILL }},
17530
17531         { &hf_smb_access_dos_date,
17532                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
17533                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
17534
17535         { &hf_smb_access_dos_time,
17536                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
17537                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
17538
17539         { &hf_smb_data_size,
17540                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
17541                 NULL, 0, "Data Size", HFILL }},
17542
17543         { &hf_smb_alloc_size,
17544                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
17545                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17546
17547         { &hf_smb_max_count,
17548                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
17549                 NULL, 0, "Maximum Count", HFILL }},
17550
17551         { &hf_smb_max_count_low,
17552                 { "Max Count Low", "smb.maxcount_low", FT_UINT16, BASE_DEC,
17553                 NULL, 0, "Maximum Count, Low 16 bits", HFILL }},
17554
17555         { &hf_smb_max_count_high,
17556                 { "Max Count High (multiply with 64K)", "smb.maxcount_high", FT_UINT16, BASE_DEC,
17557                 NULL, 0, "Maximum Count, High 16 bits", HFILL }},
17558
17559         { &hf_smb_min_count,
17560                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
17561                 NULL, 0, "Minimum Count", HFILL }},
17562
17563         { &hf_smb_timeout,
17564                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
17565                 NULL, 0, "Timeout in miliseconds", HFILL }},
17566
17567         { &hf_smb_high_offset,
17568                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
17569                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
17570
17571         { &hf_smb_units,
17572                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
17573                 NULL, 0, "Total number of units at server", HFILL }},
17574
17575         { &hf_smb_bpu,
17576                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
17577                 NULL, 0, "Blocks per unit at server", HFILL }},
17578
17579         { &hf_smb_blocksize,
17580                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
17581                 NULL, 0, "Block size (in bytes) at server", HFILL }},
17582
17583         { &hf_smb_freeunits,
17584                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
17585                 NULL, 0, "Number of free units at server", HFILL }},
17586
17587         { &hf_smb_data_offset,
17588                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17589                 NULL, 0, "Data Offset", HFILL }},
17590
17591         { &hf_smb_dcm,
17592                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
17593                 NULL, 0, "Data Compaction Mode", HFILL }},
17594
17595         { &hf_smb_request_mask,
17596                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
17597                 NULL, 0, "Connectionless mode mask", HFILL }},
17598
17599         { &hf_smb_response_mask,
17600                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
17601                 NULL, 0, "Connectionless mode mask", HFILL }},
17602
17603         { &hf_smb_search_id,
17604                 { "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
17605                 NULL, 0, "Search ID, handle for find operations", HFILL }},
17606
17607         { &hf_smb_write_mode_write_through,
17608                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
17609                 TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
17610
17611         { &hf_smb_write_mode_return_remaining,
17612                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
17613                 TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
17614
17615         { &hf_smb_write_mode_raw,
17616                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
17617                 TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
17618
17619         { &hf_smb_write_mode_message_start,
17620                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
17621                 TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
17622
17623         { &hf_smb_write_mode_connectionless,
17624                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
17625                 TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
17626
17627         { &hf_smb_resume_key_len,
17628                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
17629                 NULL, 0, "Resume Key length", HFILL }},
17630
17631         { &hf_smb_resume_find_id,
17632                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
17633                 NULL, 0, "Handle for Find operation", HFILL }},
17634
17635         { &hf_smb_resume_server_cookie,
17636                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
17637                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
17638
17639         { &hf_smb_resume_client_cookie,
17640                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
17641                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
17642
17643         { &hf_smb_andxoffset,
17644                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
17645                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
17646
17647         { &hf_smb_lock_type_large,
17648                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
17649                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
17650
17651         { &hf_smb_lock_type_cancel,
17652                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
17653                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
17654
17655         { &hf_smb_lock_type_change,
17656                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
17657                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
17658
17659         { &hf_smb_lock_type_oplock,
17660                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
17661                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
17662
17663         { &hf_smb_lock_type_shared,
17664                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
17665                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
17666
17667         { &hf_smb_locking_ol,
17668                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
17669                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
17670
17671         { &hf_smb_number_of_locks,
17672                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
17673                 NULL, 0, "Number of lock requests in this request", HFILL }},
17674
17675         { &hf_smb_number_of_unlocks,
17676                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
17677                 NULL, 0, "Number of unlock requests in this request", HFILL }},
17678
17679         { &hf_smb_lock_long_length,
17680                 { "Length", "smb.lock.length", FT_STRING, BASE_DEC,
17681                 NULL, 0, "Length of lock/unlock region", HFILL }},
17682
17683         { &hf_smb_lock_long_offset,
17684                 { "Offset", "smb.lock.offset", FT_STRING, BASE_DEC,
17685                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
17686
17687         { &hf_smb_file_type,
17688                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
17689                 VALS(filetype_vals), 0, "Type of file", HFILL }},
17690
17691         { &hf_smb_ipc_state_nonblocking,
17692                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
17693                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
17694
17695         { &hf_smb_ipc_state_endpoint,
17696                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
17697                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
17698
17699         { &hf_smb_ipc_state_pipe_type,
17700                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
17701                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
17702
17703         { &hf_smb_ipc_state_read_mode,
17704                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
17705                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
17706
17707         { &hf_smb_ipc_state_icount,
17708                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
17709                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
17710
17711         { &hf_smb_server_fid,
17712                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
17713                 NULL, 0, "Server unique File ID", HFILL }},
17714
17715         { &hf_smb_open_flags_add_info,
17716                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
17717                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
17718
17719         { &hf_smb_open_flags_ex_oplock,
17720                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
17721                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
17722
17723         { &hf_smb_open_flags_batch_oplock,
17724                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
17725                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
17726
17727         { &hf_smb_open_flags_ealen,
17728                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
17729                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
17730
17731         { &hf_smb_open_action_open,
17732                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
17733                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
17734
17735         { &hf_smb_open_action_lock,
17736                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
17737                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
17738
17739         { &hf_smb_vc_num,
17740                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
17741                 NULL, 0, "VC Number", HFILL }},
17742
17743         { &hf_smb_password_len,
17744                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
17745                 NULL, 0, "Length of password", HFILL }},
17746
17747         { &hf_smb_ansi_password_len,
17748                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
17749                 NULL, 0, "Length of ANSI password", HFILL }},
17750
17751         { &hf_smb_unicode_password_len,
17752                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
17753                 NULL, 0, "Length of Unicode password", HFILL }},
17754
17755         { &hf_smb_account,
17756                 { "Account", "smb.account", FT_STRING, BASE_NONE,
17757                 NULL, 0, "Account, username", HFILL }},
17758
17759         { &hf_smb_os,
17760                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
17761                 NULL, 0, "Which OS we are running", HFILL }},
17762
17763         { &hf_smb_lanman,
17764                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
17765                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
17766
17767         { &hf_smb_setup_action_guest,
17768                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
17769                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
17770
17771         { &hf_smb_fs,
17772                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
17773                 NULL, 0, "Native File System", HFILL }},
17774
17775         { &hf_smb_connect_flags_dtid,
17776                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
17777                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
17778
17779         { &hf_smb_connect_support_search,
17780                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
17781                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
17782
17783         { &hf_smb_connect_support_in_dfs,
17784                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
17785                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
17786
17787         { &hf_smb_max_setup_count,
17788                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
17789                 NULL, 0, "Maximum number of setup words to return", HFILL }},
17790
17791         { &hf_smb_total_param_count,
17792                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
17793                 NULL, 0, "Total number of parameter bytes", HFILL }},
17794
17795         { &hf_smb_total_data_count,
17796                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
17797                 NULL, 0, "Total number of data bytes", HFILL }},
17798
17799         { &hf_smb_max_param_count,
17800                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
17801                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
17802
17803         { &hf_smb_max_data_count,
17804                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
17805                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
17806
17807         { &hf_smb_param_disp16,
17808                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
17809                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17810
17811         { &hf_smb_param_count16,
17812                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
17813                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17814
17815         { &hf_smb_param_offset16,
17816                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
17817                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17818
17819         { &hf_smb_param_disp32,
17820                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
17821                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17822
17823         { &hf_smb_param_count32,
17824                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
17825                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17826
17827         { &hf_smb_param_offset32,
17828                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
17829                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17830
17831         { &hf_smb_data_count16,
17832                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
17833                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17834
17835         { &hf_smb_data_disp16,
17836                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
17837                 NULL, 0, "Data Displacement", HFILL }},
17838
17839         { &hf_smb_data_offset16,
17840                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17841                 NULL, 0, "Data Offset", HFILL }},
17842
17843         { &hf_smb_data_count32,
17844                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
17845                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17846
17847         { &hf_smb_data_disp32,
17848                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
17849                 NULL, 0, "Data Displacement", HFILL }},
17850
17851         { &hf_smb_data_offset32,
17852                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
17853                 NULL, 0, "Data Offset", HFILL }},
17854
17855         { &hf_smb_setup_count,
17856                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
17857                 NULL, 0, "Number of setup words in this buffer", HFILL }},
17858
17859         { &hf_smb_nt_trans_subcmd,
17860                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
17861                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
17862
17863         { &hf_smb_nt_ioctl_function_code,
17864                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
17865                 NULL, 0, "NT IOCTL function code", HFILL }},
17866
17867         { &hf_smb_nt_ioctl_isfsctl,
17868                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
17869                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
17870
17871         { &hf_smb_nt_ioctl_flags_root_handle,
17872                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
17873                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
17874
17875         { &hf_smb_nt_ioctl_data,
17876                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
17877                 NULL, 0, "Data for the IOCTL call", HFILL }},
17878
17879         { &hf_smb_nt_notify_action,
17880                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
17881                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
17882
17883         { &hf_smb_nt_notify_watch_tree,
17884                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
17885                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
17886
17887         { &hf_smb_nt_notify_stream_write,
17888                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
17889                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
17890
17891         { &hf_smb_nt_notify_stream_size,
17892                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
17893                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
17894
17895         { &hf_smb_nt_notify_stream_name,
17896                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
17897                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
17898
17899         { &hf_smb_nt_notify_security,
17900                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
17901                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
17902
17903         { &hf_smb_nt_notify_ea,
17904                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
17905                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
17906
17907         { &hf_smb_nt_notify_creation,
17908                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
17909                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
17910
17911         { &hf_smb_nt_notify_last_access,
17912                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
17913                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
17914
17915         { &hf_smb_nt_notify_last_write,
17916                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
17917                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
17918
17919         { &hf_smb_nt_notify_size,
17920                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
17921                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
17922
17923         { &hf_smb_nt_notify_attributes,
17924                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
17925                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
17926
17927         { &hf_smb_nt_notify_dir_name,
17928                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
17929                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
17930
17931         { &hf_smb_nt_notify_file_name,
17932                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
17933                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
17934
17935         { &hf_smb_root_dir_fid,
17936                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
17937                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
17938
17939         { &hf_smb_alloc_size64,
17940                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
17941                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17942
17943         { &hf_smb_nt_create_disposition,
17944                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
17945                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
17946
17947         { &hf_smb_sd_length,
17948                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
17949                 NULL, 0, "Total length of security descriptor", HFILL }},
17950
17951         { &hf_smb_ea_list_length,
17952                 { "EA List Length", "smb.ea.list_length", FT_UINT32, BASE_DEC,
17953                 NULL, 0, "Total length of extended attributes", HFILL }},
17954
17955         { &hf_smb_ea_flags,
17956                 { "EA Flags", "smb.ea.flags", FT_UINT8, BASE_HEX,
17957                 NULL, 0, "EA Flags", HFILL }},
17958
17959         { &hf_smb_ea_name_length,
17960                 { "EA Name Length", "smb.ea.name_length", FT_UINT8, BASE_DEC,
17961                 NULL, 0, "EA Name Length", HFILL }},
17962
17963         { &hf_smb_ea_data_length,
17964                 { "EA Data Length", "smb.ea.data_length", FT_UINT16, BASE_DEC,
17965                 NULL, 0, "EA Data Length", HFILL }},
17966
17967         { &hf_smb_ea_name,
17968                 { "EA Name", "smb.ea.name", FT_STRING, BASE_NONE,
17969                 NULL, 0, "EA Name", HFILL }},
17970
17971         { &hf_smb_ea_data,
17972                 { "EA Data", "smb.ea.data", FT_BYTES, BASE_NONE,
17973                 NULL, 0, "EA Data", HFILL }},
17974
17975         { &hf_smb_file_name_len,
17976                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
17977                 NULL, 0, "Length of File Name", HFILL }},
17978
17979         { &hf_smb_nt_impersonation_level,
17980                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
17981                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
17982
17983         { &hf_smb_nt_security_flags_context_tracking,
17984                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
17985                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
17986
17987         { &hf_smb_nt_security_flags_effective_only,
17988                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
17989                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
17990
17991         { &hf_smb_nt_access_mask_generic_read,
17992                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
17993                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
17994
17995         { &hf_smb_nt_access_mask_generic_write,
17996                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
17997                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
17998
17999         { &hf_smb_nt_access_mask_generic_execute,
18000                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
18001                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
18002
18003         { &hf_smb_nt_access_mask_generic_all,
18004                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
18005                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
18006
18007         { &hf_smb_nt_access_mask_maximum_allowed,
18008                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
18009                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
18010
18011         { &hf_smb_nt_access_mask_system_security,
18012                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
18013                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
18014
18015         { &hf_smb_nt_access_mask_synchronize,
18016                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
18017                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
18018
18019         { &hf_smb_nt_access_mask_write_owner,
18020                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
18021                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
18022
18023         { &hf_smb_nt_access_mask_write_dac,
18024                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
18025                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
18026
18027         { &hf_smb_nt_access_mask_read_control,
18028                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
18029                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
18030
18031         { &hf_smb_nt_access_mask_delete,
18032                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
18033                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
18034
18035         { &hf_smb_nt_access_mask_write_attributes,
18036                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
18037                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
18038
18039         { &hf_smb_nt_access_mask_read_attributes,
18040                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
18041                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
18042
18043         { &hf_smb_nt_access_mask_delete_child,
18044                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
18045                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
18046
18047         /*
18048          * "Execute" for files, "traverse" for directories.
18049          */
18050         { &hf_smb_nt_access_mask_execute,
18051                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
18052                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
18053
18054         { &hf_smb_nt_access_mask_write_ea,
18055                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
18056                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
18057
18058         { &hf_smb_nt_access_mask_read_ea,
18059                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
18060                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
18061
18062         /*
18063          * "Append data" for files, "add subdirectory" for directories,
18064          * "create pipe instance" for named pipes.
18065          */
18066         { &hf_smb_nt_access_mask_append,
18067                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
18068                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
18069
18070         /*
18071          * "Write data" for files and pipes, "add file" for directory.
18072          */
18073         { &hf_smb_nt_access_mask_write,
18074                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
18075                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
18076
18077         /*
18078          * "Read data" for files and pipes, "list directory" for directory.
18079          */
18080         { &hf_smb_nt_access_mask_read,
18081                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
18082                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
18083
18084         { &hf_smb_nt_create_bits_oplock,
18085                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
18086                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
18087
18088         { &hf_smb_nt_create_bits_boplock,
18089                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
18090                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
18091
18092         { &hf_smb_nt_create_bits_dir,
18093                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
18094                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
18095
18096         { &hf_smb_nt_create_bits_ext_resp,
18097           { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32, 
18098             TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
18099
18100         { &hf_smb_nt_create_options_directory_file,
18101                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
18102                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
18103
18104         { &hf_smb_nt_create_options_write_through,
18105                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
18106                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
18107
18108         { &hf_smb_nt_create_options_sequential_only,
18109                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
18110                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
18111
18112         { &hf_smb_nt_create_options_sync_io_alert,
18113                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
18114                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
18115
18116         { &hf_smb_nt_create_options_sync_io_nonalert,
18117                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
18118                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
18119
18120         { &hf_smb_nt_create_options_non_directory_file,
18121                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
18122                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
18123
18124         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
18125            and "NtOpenFile()"; is that sent over the wire?  Network
18126            Monitor thinks so, but its author may just have grabbed
18127            the flag bits from a system header file. */
18128
18129         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
18130            and "NtOpenFile()"; is that sent over the wire?  NetMon
18131            thinks so, but see previous comment. */
18132
18133         { &hf_smb_nt_create_options_no_ea_knowledge,
18134                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
18135                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
18136
18137         { &hf_smb_nt_create_options_eight_dot_three_only,
18138                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
18139                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
18140
18141         { &hf_smb_nt_create_options_random_access,
18142                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
18143                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
18144
18145         { &hf_smb_nt_create_options_delete_on_close,
18146                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
18147                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
18148
18149         /* 0x00002000 is "open by FID", or something such as that (which
18150            I suspect is like "open by inumber" on UNIX), at least in
18151            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
18152            wire?  NetMon thinks so, but see previous comment. */
18153
18154         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
18155            and "NtOpenFile()"; is that sent over the wire?  NetMon
18156            thinks so, but see previous comment. */
18157
18158         { &hf_smb_nt_share_access_read,
18159                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
18160                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
18161
18162         { &hf_smb_nt_share_access_write,
18163                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
18164                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
18165
18166         { &hf_smb_nt_share_access_delete,
18167                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
18168                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
18169
18170         { &hf_smb_file_eattr_read_only,
18171                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
18172                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
18173
18174         { &hf_smb_file_eattr_hidden,
18175                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
18176                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
18177
18178         { &hf_smb_file_eattr_system,
18179                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
18180                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
18181
18182         { &hf_smb_file_eattr_volume,
18183                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
18184                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
18185
18186         { &hf_smb_file_eattr_directory,
18187                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
18188                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
18189
18190         { &hf_smb_file_eattr_archive,
18191                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
18192                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
18193
18194         { &hf_smb_file_eattr_device,
18195                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
18196                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
18197
18198         { &hf_smb_file_eattr_normal,
18199                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
18200                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
18201
18202         { &hf_smb_file_eattr_temporary,
18203                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
18204                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
18205
18206         { &hf_smb_file_eattr_sparse,
18207                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
18208                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
18209
18210         { &hf_smb_file_eattr_reparse,
18211                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
18212                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
18213
18214         { &hf_smb_file_eattr_compressed,
18215                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
18216                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
18217
18218         { &hf_smb_file_eattr_offline,
18219                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
18220                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
18221
18222         { &hf_smb_file_eattr_not_content_indexed,
18223                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
18224                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
18225
18226         { &hf_smb_file_eattr_encrypted,
18227                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
18228                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
18229
18230         { &hf_smb_sec_desc_len,
18231                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
18232                 NULL, 0, "Security Descriptor Length", HFILL }},
18233
18234         { &hf_smb_nt_qsd_owner,
18235                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
18236                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
18237
18238         { &hf_smb_nt_qsd_group,
18239                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
18240                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
18241
18242         { &hf_smb_nt_qsd_dacl,
18243                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
18244                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
18245
18246         { &hf_smb_nt_qsd_sacl,
18247                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
18248                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
18249
18250         { &hf_smb_extended_attributes,
18251                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
18252                 NULL, 0, "Extended Attributes", HFILL }},
18253
18254         { &hf_smb_oplock_level,
18255                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
18256                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
18257
18258         { &hf_smb_create_action,
18259                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
18260                 VALS(oa_open_vals), 0, "Type of action taken", HFILL }},
18261
18262         { &hf_smb_file_id,
18263                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
18264                 NULL, 0, "Server unique file ID", HFILL }},
18265
18266         { &hf_smb_ea_error_offset,
18267                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
18268                 NULL, 0, "Offset into EA list if EA error", HFILL }},
18269
18270         { &hf_smb_end_of_file,
18271                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
18272                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
18273
18274         { &hf_smb_device_type,
18275                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
18276                 VALS(device_type_vals), 0, "Type of device", HFILL }},
18277
18278         { &hf_smb_is_directory,
18279                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
18280                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
18281
18282         { &hf_smb_next_entry_offset,
18283                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
18284                 NULL, 0, "Offset to next entry", HFILL }},
18285
18286         { &hf_smb_change_time,
18287                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
18288                 NULL, 0, "Last Change Time", HFILL }},
18289
18290         { &hf_smb_setup_len,
18291                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
18292                 NULL, 0, "Length of printer setup data", HFILL }},
18293
18294         { &hf_smb_print_mode,
18295                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
18296                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
18297
18298         { &hf_smb_print_identifier,
18299                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
18300                 NULL, 0, "Identifier string for this print job", HFILL }},
18301
18302         { &hf_smb_restart_index,
18303                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
18304                 NULL, 0, "Index of entry after last returned", HFILL }},
18305
18306         { &hf_smb_print_queue_date,
18307                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
18308                 NULL, 0, "Date when this entry was queued", HFILL }},
18309
18310         { &hf_smb_print_queue_dos_date,
18311                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
18312                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
18313
18314         { &hf_smb_print_queue_dos_time,
18315                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
18316                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
18317
18318         { &hf_smb_print_status,
18319                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
18320                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
18321
18322         { &hf_smb_print_spool_file_number,
18323                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
18324                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
18325
18326         { &hf_smb_print_spool_file_size,
18327                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
18328                 NULL, 0, "Number of bytes in spool file", HFILL }},
18329
18330         { &hf_smb_print_spool_file_name,
18331                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
18332                 NULL, 0, "Name of client that submitted this job", HFILL }},
18333
18334         { &hf_smb_start_index,
18335                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
18336                 NULL, 0, "First queue entry to return", HFILL }},
18337
18338         { &hf_smb_originator_name,
18339                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
18340                 NULL, 0, "Name of sender of message", HFILL }},
18341
18342         { &hf_smb_destination_name,
18343                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
18344                 NULL, 0, "Name of recipient of message", HFILL }},
18345
18346         { &hf_smb_message_len,
18347                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
18348                 NULL, 0, "Length of message", HFILL }},
18349
18350         { &hf_smb_message,
18351                 { "Message", "smb.message", FT_STRING, BASE_NONE,
18352                 NULL, 0, "Message text", HFILL }},
18353
18354         { &hf_smb_mgid,
18355                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
18356                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
18357
18358         { &hf_smb_forwarded_name,
18359                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
18360                 NULL, 0, "Recipient name being forwarded", HFILL }},
18361
18362         { &hf_smb_machine_name,
18363                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
18364                 NULL, 0, "Name of target machine", HFILL }},
18365
18366         { &hf_smb_cancel_to,
18367                 { "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
18368                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
18369
18370         { &hf_smb_trans2_subcmd,
18371                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
18372                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
18373
18374         { &hf_smb_trans_name,
18375                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
18376                 NULL, 0, "Name of transaction", HFILL }},
18377
18378         { &hf_smb_transaction_flags_dtid,
18379                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
18380                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
18381
18382         { &hf_smb_transaction_flags_owt,
18383                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
18384                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
18385
18386         { &hf_smb_search_count,
18387                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
18388                 NULL, 0, "Maximum number of search entries to return", HFILL }},
18389
18390         { &hf_smb_search_pattern,
18391                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
18392                 NULL, 0, "Search Pattern", HFILL }},
18393
18394         { &hf_smb_ff2_backup,
18395                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
18396                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
18397
18398         { &hf_smb_ff2_continue,
18399                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
18400                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
18401
18402         { &hf_smb_ff2_resume,
18403                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
18404                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
18405
18406         { &hf_smb_ff2_close_eos,
18407                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
18408                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
18409
18410         { &hf_smb_ff2_close,
18411                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
18412                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
18413
18414         { &hf_smb_ff2_information_level,
18415                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
18416                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
18417
18418         { &hf_smb_qpi_loi,
18419                 { "Level of Interest", "smb.qpi_loi", FT_UINT16, BASE_DEC,
18420                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] QUERY_{FILE,PATH}_INFO commands", HFILL }},
18421
18422         { &hf_smb_spi_loi,
18423                 { "Level of Interest", "smb.spi_loi", FT_UINT16, BASE_DEC,
18424                 VALS(spi_loi_vals), 0, "Level of interest for TRANSACTION[2] SET_{FILE,PATH}_INFO commands", HFILL }},
18425
18426 #if 0
18427         { &hf_smb_sfi_writetru,
18428                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
18429                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
18430
18431         { &hf_smb_sfi_caching,
18432                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
18433                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
18434 #endif
18435
18436         { &hf_smb_storage_type,
18437                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
18438                 NULL, 0, "Type of storage", HFILL }},
18439
18440         { &hf_smb_resume,
18441                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
18442                 NULL, 0, "Resume Key", HFILL }},
18443
18444         { &hf_smb_max_referral_level,
18445                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
18446                 NULL, 0, "Latest referral version number understood", HFILL }},
18447
18448         { &hf_smb_qfsi_information_level,
18449                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_HEX,
18450                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
18451
18452         { &hf_smb_nt_rename_level,
18453                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
18454                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
18455
18456         { &hf_smb_cluster_count,
18457                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
18458                 NULL, 0, "Number of clusters", HFILL }},
18459
18460         { &hf_smb_number_of_links,
18461                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
18462                 NULL, 0, "Number of hard links to the file", HFILL }},
18463
18464         { &hf_smb_delete_pending,
18465                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
18466                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
18467
18468         { &hf_smb_index_number,
18469                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
18470                 NULL, 0, "File system unique identifier", HFILL }},
18471
18472         { &hf_smb_current_offset,
18473                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
18474                 NULL, 0, "Current offset in the file", HFILL }},
18475
18476         { &hf_smb_t2_alignment,
18477                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
18478                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
18479
18480         { &hf_smb_t2_stream_name_length,
18481                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
18482                 NULL, 0, "Length of stream name", HFILL }},
18483
18484         { &hf_smb_t2_stream_size,
18485                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
18486                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18487
18488         { &hf_smb_t2_stream_name,
18489                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
18490                 NULL, 0, "Name of the stream", HFILL }},
18491
18492         { &hf_smb_t2_compressed_file_size,
18493                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
18494                 NULL, 0, "Size of the compressed file", HFILL }},
18495
18496         { &hf_smb_t2_compressed_format,
18497                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
18498                 NULL, 0, "Compression algorithm used", HFILL }},
18499
18500         { &hf_smb_t2_compressed_unit_shift,
18501                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
18502                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18503
18504         { &hf_smb_t2_compressed_chunk_shift,
18505                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
18506                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18507
18508         { &hf_smb_t2_compressed_cluster_shift,
18509                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
18510                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18511
18512         { &hf_smb_t2_marked_for_deletion,
18513                 { "Marked for Deletion", "smb.marked_for_deletion", FT_BOOLEAN, BASE_NONE,
18514                 TFS(&tfs_marked_for_deletion), 0x0, "Marked for deletion?", HFILL }},
18515
18516         { &hf_smb_dfs_path_consumed,
18517                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
18518                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
18519
18520         { &hf_smb_dfs_num_referrals,
18521                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
18522                 NULL, 0, "Number of referrals in this pdu", HFILL }},
18523
18524         { &hf_smb_get_dfs_server_hold_storage,
18525                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
18526                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
18527
18528         { &hf_smb_get_dfs_fielding,
18529                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
18530                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
18531
18532         { &hf_smb_dfs_referral_version,
18533                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
18534                 NULL, 0, "Version of referral element", HFILL }},
18535
18536         { &hf_smb_dfs_referral_size,
18537                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
18538                 NULL, 0, "Size of referral element", HFILL }},
18539
18540         { &hf_smb_dfs_referral_server_type,
18541                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
18542                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
18543
18544         { &hf_smb_dfs_referral_flags_strip,
18545                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
18546                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
18547
18548         { &hf_smb_dfs_referral_node_offset,
18549                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
18550                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
18551
18552         { &hf_smb_dfs_referral_node,
18553                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
18554                 NULL, 0, "Name of entity to visit next", HFILL }},
18555
18556         { &hf_smb_dfs_referral_proximity,
18557                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
18558                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
18559
18560         { &hf_smb_dfs_referral_ttl,
18561                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
18562                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
18563
18564         { &hf_smb_dfs_referral_path_offset,
18565                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
18566                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
18567
18568         { &hf_smb_dfs_referral_path,
18569                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
18570                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
18571
18572         { &hf_smb_dfs_referral_alt_path_offset,
18573                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
18574                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
18575
18576         { &hf_smb_dfs_referral_alt_path,
18577                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
18578                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
18579
18580         { &hf_smb_end_of_search,
18581                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
18582                 NULL, 0, "Was last entry returned?", HFILL }},
18583
18584         { &hf_smb_last_name_offset,
18585                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
18586                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
18587
18588         { &hf_smb_fn_information_level,
18589                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
18590                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
18591
18592         { &hf_smb_monitor_handle,
18593                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
18594                 NULL, 0, "Handle for Find Notify operations", HFILL }},
18595
18596         { &hf_smb_change_count,
18597                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
18598                 NULL, 0, "Number of changes to wait for", HFILL }},
18599
18600         { &hf_smb_file_index,
18601                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
18602                 NULL, 0, "File index", HFILL }},
18603
18604         { &hf_smb_short_file_name,
18605                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
18606                 NULL, 0, "Short (8.3) File Name", HFILL }},
18607
18608         { &hf_smb_short_file_name_len,
18609                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
18610                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
18611
18612         { &hf_smb_fs_id,
18613                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
18614                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
18615
18616         { &hf_smb_fs_guid,
18617                 { "FS GUID", "smb.fs_guid", FT_STRING, BASE_NONE,
18618                 NULL, 0, "File System GUID", HFILL }},
18619
18620         { &hf_smb_sector_unit,
18621                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
18622                 NULL, 0, "Sectors per allocation unit", HFILL }},
18623
18624         { &hf_smb_fs_units,
18625                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
18626                 NULL, 0, "Total number of units on this filesystem", HFILL }},
18627
18628         { &hf_smb_fs_sector,
18629                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
18630                 NULL, 0, "Bytes per sector", HFILL }},
18631
18632         { &hf_smb_avail_units,
18633                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
18634                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
18635
18636         { &hf_smb_volume_serial_num,
18637                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
18638                 NULL, 0, "Volume serial number", HFILL }},
18639
18640         { &hf_smb_volume_label_len,
18641                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
18642                 NULL, 0, "Length of volume label", HFILL }},
18643
18644         { &hf_smb_volume_label,
18645                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
18646                 NULL, 0, "Volume label", HFILL }},
18647
18648         { &hf_smb_free_alloc_units64,
18649                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
18650                 NULL, 0, "Number of free allocation units", HFILL }},
18651
18652         { &hf_smb_caller_free_alloc_units64,
18653                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
18654                 NULL, 0, "Number of caller free allocation units", HFILL }},
18655
18656         { &hf_smb_actual_free_alloc_units64,
18657                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
18658                 NULL, 0, "Number of actual free allocation units", HFILL }},
18659
18660         { &hf_smb_soft_quota_limit,
18661                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
18662                 NULL, 0, "Soft Quota treshold", HFILL }},
18663
18664         { &hf_smb_hard_quota_limit,
18665                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
18666                 NULL, 0, "Hard Quota limit", HFILL }},
18667
18668         { &hf_smb_user_quota_used,
18669                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
18670                 NULL, 0, "How much Quota is used by this user", HFILL }},
18671
18672         { &hf_smb_max_name_len,
18673                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
18674                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
18675
18676         { &hf_smb_fs_name_len,
18677                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
18678                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
18679
18680         { &hf_smb_fs_name,
18681                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
18682                 NULL, 0, "Name of filesystem", HFILL }},
18683
18684         { &hf_smb_device_char_removable,
18685                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
18686                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
18687
18688         { &hf_smb_device_char_read_only,
18689                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
18690                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
18691
18692         { &hf_smb_device_char_floppy,
18693                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
18694                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
18695
18696         { &hf_smb_device_char_write_once,
18697                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
18698                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
18699
18700         { &hf_smb_device_char_remote,
18701                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
18702                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
18703
18704         { &hf_smb_device_char_mounted,
18705                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
18706                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
18707
18708         { &hf_smb_device_char_virtual,
18709                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
18710                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
18711
18712         { &hf_smb_fs_attr_css,
18713                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
18714                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
18715
18716         { &hf_smb_fs_attr_cpn,
18717                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
18718                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
18719
18720         { &hf_smb_fs_attr_pacls,
18721                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
18722                 TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
18723
18724         { &hf_smb_fs_attr_fc,
18725                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
18726                 TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
18727
18728         { &hf_smb_fs_attr_vq,
18729                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
18730                 TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
18731
18732         { &hf_smb_fs_attr_dim,
18733                 { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
18734                 TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
18735
18736         { &hf_smb_fs_attr_vic,
18737                 { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
18738                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
18739
18740         { &hf_smb_sec_desc_revision,
18741                 { "Revision", "smb.sec_desc.revision", FT_UINT8, BASE_DEC,
18742                 NULL, 0, "Version of NT Security Descriptor structure", HFILL }},
18743
18744         { &hf_smb_sid,
18745                 { "SID", "smb.sid", FT_STRING, BASE_DEC,
18746                 NULL, 0, "SID: Security Identifier", HFILL }},
18747
18748         { &hf_smb_sid_revision,
18749                 { "Revision", "smb.sid.revision", FT_UINT8, BASE_DEC,
18750                 NULL, 0, "Version of SID structure", HFILL }},
18751
18752         { &hf_smb_sid_num_auth,
18753                 { "Num Auth", "smb.sid.num_auth", FT_UINT8, BASE_DEC,
18754                 NULL, 0, "Number of authorities for this SID", HFILL }},
18755
18756         { &hf_smb_acl_revision,
18757                 { "Revision", "smb.acl.revision", FT_UINT16, BASE_DEC,
18758                 NULL, 0, "Version of NT ACL structure", HFILL }},
18759
18760         { &hf_smb_acl_size,
18761                 { "Size", "smb.acl.size", FT_UINT16, BASE_DEC,
18762                 NULL, 0, "Size of NT ACL structure", HFILL }},
18763
18764         { &hf_smb_acl_num_aces,
18765                 { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
18766                 NULL, 0, "Number of ACE structures for this ACL", HFILL }},
18767
18768         { &hf_smb_user_quota_offset,
18769                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
18770                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
18771
18772         { &hf_smb_ace_type,
18773                 { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
18774                 VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
18775
18776         { &hf_smb_pipe_write_len,
18777                 { "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
18778                 NULL, 0, "Number of bytes written to pipe", HFILL }},
18779
18780         { &hf_smb_ace_size,
18781                 { "Size", "smb.ace.size", FT_UINT16, BASE_DEC,
18782                 NULL, 0, "Size of this ACE", HFILL }},
18783
18784         { &hf_smb_ace_flags_object_inherit,
18785                 { "Object Inherit", "smb.ace.flags.object_inherit", FT_BOOLEAN, 8,
18786                 TFS(&tfs_ace_flags_object_inherit), 0x01, "Will subordinate files inherit this ACE?", HFILL }},
18787
18788         { &hf_smb_ace_flags_container_inherit,
18789                 { "Container Inherit", "smb.ace.flags.container_inherit", FT_BOOLEAN, 8,
18790                 TFS(&tfs_ace_flags_container_inherit), 0x02, "Will subordinate containers inherit this ACE?", HFILL }},
18791
18792         { &hf_smb_ace_flags_non_propagate_inherit,
18793                 { "Non-Propagate Inherit", "smb.ace.flags.non_propagate_inherit", FT_BOOLEAN, 8,
18794                 TFS(&tfs_ace_flags_non_propagate_inherit), 0x04, "Will subordinate object propagate this ACE further?", HFILL }},
18795
18796         { &hf_smb_ace_flags_inherit_only,
18797                 { "Inherit Only", "smb.ace.flags.inherit_only", FT_BOOLEAN, 8,
18798                 TFS(&tfs_ace_flags_inherit_only), 0x08, "Does this ACE apply to the current object?", HFILL }},
18799
18800         { &hf_smb_ace_flags_inherited_ace,
18801                 { "Inherited ACE", "smb.ace.flags.inherited_ace", FT_BOOLEAN, 8,
18802                 TFS(&tfs_ace_flags_inherited_ace), 0x10, "Was this ACE inherited from its parent object?", HFILL }},
18803
18804         { &hf_smb_ace_flags_successful_access,
18805                 { "Audit Successful Accesses", "smb.ace.flags.successful_access", FT_BOOLEAN, 8,
18806                 TFS(&tfs_ace_flags_successful_access), 0x40, "Should successful accesses be audited?", HFILL }},
18807
18808         { &hf_smb_ace_flags_failed_access,
18809                 { "Audit Failed Accesses", "smb.ace.flags.failed_access", FT_BOOLEAN, 8,
18810                 TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
18811
18812         { &hf_smb_sec_desc_type_owner_defaulted,
18813                 { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
18814                 TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
18815
18816         { &hf_smb_sec_desc_type_group_defaulted,
18817                 { "Group Defaulted", "smb.sec_desc.type.group_defaulted", FT_BOOLEAN, 16,
18818                 TFS(&tfs_sec_desc_type_group_defaulted), 0x0002, "Is Group Defaulted?", HFILL }},
18819
18820         { &hf_smb_sec_desc_type_dacl_present,
18821                 { "DACL Present", "smb.sec_desc.type.dacl_present", FT_BOOLEAN, 16,
18822                 TFS(&tfs_sec_desc_type_dacl_present), 0x0004, "Does this SecDesc have DACL present?", HFILL }},
18823
18824         { &hf_smb_sec_desc_type_dacl_defaulted,
18825                 { "DACL Defaulted", "smb.sec_desc.type.dacl_defaulted", FT_BOOLEAN, 16,
18826                 TFS(&tfs_sec_desc_type_dacl_defaulted), 0x0008, "Does this SecDesc have DACL Defaulted?", HFILL }},
18827
18828         { &hf_smb_sec_desc_type_sacl_present,
18829                 { "SACL Present", "smb.sec_desc.type.sacl_present", FT_BOOLEAN, 16,
18830                 TFS(&tfs_sec_desc_type_sacl_present), 0x0010, "Is the SACL present?", HFILL }},
18831
18832         { &hf_smb_sec_desc_type_sacl_defaulted,
18833                 { "SACL Defaulted", "smb.sec_desc.type.sacl_defaulted", FT_BOOLEAN, 16,
18834                 TFS(&tfs_sec_desc_type_sacl_defaulted), 0x0020, "Does this SecDesc have SACL Defaulted?", HFILL }},
18835
18836         { &hf_smb_sec_desc_type_dacl_auto_inherit_req,
18837                 { "DACL Auto Inherit Required", "smb.sec_desc.type.dacl_auto_inherit_req", FT_BOOLEAN, 16,
18838                 TFS(&tfs_sec_desc_type_dacl_auto_inherit_req), 0x0100, "Does this SecDesc have DACL Auto Inherit Required set?", HFILL }},
18839
18840         { &hf_smb_sec_desc_type_sacl_auto_inherit_req,
18841                 { "SACL Auto Inherit Required", "smb.sec_desc.type.sacl_auto_inherit_req", FT_BOOLEAN, 16,
18842                 TFS(&tfs_sec_desc_type_sacl_auto_inherit_req), 0x0200, "Does this SecDesc have SACL Auto Inherit Required set?", HFILL }},
18843
18844         { &hf_smb_sec_desc_type_dacl_auto_inherited,
18845                 { "DACL Auto Inherited", "smb.sec_desc.type.dacl_auto_inherited", FT_BOOLEAN, 16,
18846                 TFS(&tfs_sec_desc_type_dacl_auto_inherited), 0x0400, "Is this DACL auto inherited", HFILL }},
18847
18848         { &hf_smb_sec_desc_type_sacl_auto_inherited,
18849                 { "SACL Auto Inherited", "smb.sec_desc.type.sacl_auto_inherited", FT_BOOLEAN, 16,
18850                 TFS(&tfs_sec_desc_type_sacl_auto_inherited), 0x0800, "Is this SACL auto inherited", HFILL }},
18851
18852         { &hf_smb_sec_desc_type_dacl_protected,
18853                 { "DACL Protected", "smb.sec_desc.type.dacl_protected", FT_BOOLEAN, 16,
18854                 TFS(&tfs_sec_desc_type_dacl_protected), 0x1000, "Is the DACL structure protected?", HFILL }},
18855
18856         { &hf_smb_sec_desc_type_sacl_protected,
18857                 { "SACL Protected", "smb.sec_desc.type.sacl_protected", FT_BOOLEAN, 16,
18858                 TFS(&tfs_sec_desc_type_sacl_protected), 0x2000, "Is the SACL structure protected?", HFILL }},
18859
18860         { &hf_smb_sec_desc_type_self_relative,
18861                 { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
18862                 TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
18863
18864         { &hf_smb_quota_flags_deny_disk,
18865                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
18866                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
18867
18868         { &hf_smb_quota_flags_log_limit,
18869                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
18870                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
18871
18872         { &hf_smb_quota_flags_log_warning,
18873                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
18874                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
18875
18876         { &hf_smb_quota_flags_enabled,
18877                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
18878                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
18879
18880         { &hf_smb_segment_overlap,
18881                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18882                         "Fragment overlaps with other fragments", HFILL }},
18883
18884         { &hf_smb_segment_overlap_conflict,
18885                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18886                         "Overlapping fragments contained conflicting data", HFILL }},
18887
18888         { &hf_smb_segment_multiple_tails,
18889                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18890                         "Several tails were found when defragmenting the packet", HFILL }},
18891
18892         { &hf_smb_segment_too_long_fragment,
18893                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18894                         "Fragment contained data past end of packet", HFILL }},
18895
18896         { &hf_smb_segment_error,
18897                 { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18898                         "Defragmentation error due to illegal fragments", HFILL }},
18899
18900         { &hf_smb_segment,
18901                 { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18902                         "SMB Segment", HFILL }},
18903
18904         { &hf_smb_segments,
18905                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
18906                         "SMB Segments", HFILL }},
18907
18908         { &hf_smb_unix_major_version,
18909           { "Major Version", "smb.unix.major_version", FT_UINT16, BASE_DEC,
18910             NULL, 0, "UNIX Major Version", HFILL }},
18911
18912         { &hf_smb_unix_minor_version,
18913           { "Minor Version", "smb.unix.minor_version", FT_UINT16, BASE_DEC,
18914             NULL, 0, "UNIX Minor Version", HFILL }},
18915
18916         { &hf_smb_unix_capability_fcntl,
18917           { "FCNTL Capability", "smb.unix.capability.fcntl", FT_BOOLEAN, 32,
18918                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
18919
18920         { &hf_smb_unix_capability_posix_acl,
18921           { "POSIX ACL Capability", "smb.unix.capability.posix_acl", FT_BOOLEAN, 32,
18922                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
18923
18924         { &hf_smb_unix_file_size,
18925           { "File size", "smb.unix.file.size", FT_UINT64, BASE_DEC,
18926             NULL, 0, "", HFILL }},
18927
18928         { &hf_smb_unix_file_num_bytes,
18929           { "Number of bytes", "smb.unix.file.num_bytes", FT_UINT64, BASE_DEC,
18930             NULL, 0, "Number of bytes used to store the file", HFILL }},
18931
18932         { &hf_smb_unix_file_last_status,
18933           { "Last status change", "smb.unix.file.stime", FT_ABSOLUTE_TIME, BASE_NONE,
18934             NULL, 0, "", HFILL }},
18935
18936         { &hf_smb_unix_file_last_access,
18937           { "Last access", "smb.unix.file.atime", FT_ABSOLUTE_TIME, BASE_NONE,
18938             NULL, 0, "", HFILL }},
18939
18940         { &hf_smb_unix_file_last_change,
18941           { "Last modification", "smb.unix.file.mtime", FT_ABSOLUTE_TIME, BASE_NONE,
18942             NULL, 0, "", HFILL }},
18943
18944         { &hf_smb_unix_file_uid,
18945           { "UID", "smb.unix.file.uid", FT_UINT64, BASE_DEC,
18946             NULL, 0, "", HFILL }},
18947
18948         { &hf_smb_unix_file_gid,
18949           { "GID", "smb.unix.file.gid", FT_UINT64, BASE_DEC,
18950             NULL, 0, "", HFILL }},
18951
18952         { &hf_smb_unix_file_type,
18953           { "File type", "smb.unix.file.file_type", FT_UINT32, BASE_DEC,
18954             VALS(unix_file_type_vals), 0, "", HFILL }},
18955
18956         { &hf_smb_unix_file_dev_major,
18957           { "Major device", "smb.unix.file.dev_major", FT_UINT64, BASE_HEX,
18958             NULL, 0, "", HFILL }},
18959
18960         { &hf_smb_unix_file_dev_minor,
18961           { "Minor device", "smb.unix.file.dev_minor", FT_UINT64, BASE_HEX,
18962             NULL, 0, "", HFILL }},
18963
18964         { &hf_smb_unix_file_unique_id,
18965           { "Unique ID", "smb.unix.file.unique_id", FT_UINT64, BASE_HEX,
18966             NULL, 0, "", HFILL }},
18967
18968         { &hf_smb_unix_file_permissions,
18969           { "File permissions", "smb.unix.file.perms", FT_UINT64, BASE_HEX,
18970             NULL, 0, "", HFILL }},
18971
18972         { &hf_smb_unix_file_nlinks,
18973           { "Num links", "smb.unix.file.num_links", FT_UINT64, BASE_DEC,
18974             NULL, 0, "", HFILL }},
18975
18976         { &hf_smb_unix_file_link_dest,
18977           { "Link destination", "smb.unix.file.link_dest", FT_STRING, 
18978             BASE_NONE, NULL, 0, "", HFILL }},
18979
18980         { &hf_smb_unix_find_file_nextoffset,
18981           { "Next entry offset", "smb.unix.find_file.next_offset", FT_UINT32, BASE_DEC,
18982             NULL, 0, "", HFILL }},
18983
18984         { &hf_smb_unix_find_file_resumekey,
18985           { "Resume key", "smb.unix.find_file.resume_key", FT_UINT32, BASE_DEC,
18986             NULL, 0, "", HFILL }},
18987
18988                 /* Access masks */
18989
18990                 { &hf_smb_access_mask,
18991                   { "Access required", "smb.access_mask",
18992                     FT_UINT32, BASE_HEX, NULL, 0x0, "Access mask",
18993                     HFILL }},
18994                 { &hf_access_generic_read,
18995                   { "Generic read", "nt.access_mask.generic_read",
18996                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18997                     GENERIC_READ_ACCESS, "Generic read", HFILL }},
18998
18999                 { &hf_access_generic_write,
19000                   { "Generic write", "nt.access_mask.generic_write",
19001                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19002                     GENERIC_WRITE_ACCESS, "Generic write", HFILL }},
19003
19004                 { &hf_access_generic_execute,
19005                   { "Generic execute", "nt.access_mask.generic_execute",
19006                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19007                     GENERIC_EXECUTE_ACCESS, "Generic execute", HFILL }},
19008
19009                 { &hf_access_generic_all,
19010                   { "Generic all", "nt.access_mask.generic_all",
19011                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19012                     GENERIC_ALL_ACCESS, "Generic all", HFILL }},
19013
19014                 { &hf_access_maximum_allowed,
19015                   { "Maximum allowed", "nt.access_mask.maximum_allowed",
19016                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19017                     MAXIMUM_ALLOWED_ACCESS, "Maximum allowed", HFILL }},
19018
19019                 { &hf_access_sacl,
19020                   { "Access SACL", "nt.access_mask.access_sacl",
19021                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19022                     ACCESS_SACL_ACCESS, "Access SACL", HFILL }},
19023
19024                 { &hf_access_standard_read_control,
19025                   { "Read control", "nt.access_mask.read_control",
19026                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19027                     READ_CONTROL_ACCESS, "Read control", HFILL }},
19028
19029                 { &hf_access_standard_delete,
19030                   { "Delete", "nt.access_mask.delete",
19031                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19032                     DELETE_ACCESS, "Delete", HFILL }},
19033
19034                 { &hf_access_standard_synchronise,
19035                   { "Synchronise", "nt.access_mask.synchronise",
19036                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19037                     SYNCHRONIZE_ACCESS, "Synchronise", HFILL }},
19038
19039                 { &hf_access_standard_write_dac,
19040                   { "Write DAC", "nt.access_mask.write_dac",
19041                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19042                     WRITE_DAC_ACCESS, "Write DAC", HFILL }},
19043
19044                 { &hf_access_standard_write_owner,
19045                   { "Write owner", "nt.access_mask.write_owner",
19046                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19047                     WRITE_OWNER_ACCESS, "Write owner", HFILL }},
19048
19049                 { &hf_access_specific_15,
19050                   { "Specific access, bit 15", "nt.access_mask.specific_15",
19051                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19052                     0x8000, "Specific access, bit 15", HFILL }},
19053
19054                 { &hf_access_specific_14,
19055                   { "Specific access, bit 14", "nt.access_mask.specific_14",
19056                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19057                     0x4000, "Specific access, bit 14", HFILL }},
19058
19059                 { &hf_access_specific_13,
19060                   { "Specific access, bit 13", "nt.access_mask.specific_13",
19061                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19062                     0x2000, "Specific access, bit 13", HFILL }},
19063
19064                 { &hf_access_specific_12,
19065                   { "Specific access, bit 12", "nt.access_mask.specific_12",
19066                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19067                     0x1000, "Specific access, bit 12", HFILL }},
19068
19069                 { &hf_access_specific_11,
19070                   { "Specific access, bit 11", "nt.access_mask.specific_11",
19071                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19072                     0x0800, "Specific access, bit 11", HFILL }},
19073
19074                 { &hf_access_specific_10,
19075                   { "Specific access, bit 10", "nt.access_mask.specific_10",
19076                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19077                     0x0400, "Specific access, bit 10", HFILL }},
19078
19079                 { &hf_access_specific_9,
19080                   { "Specific access, bit 9", "nt.access_mask.specific_9",
19081                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19082                     0x0200, "Specific access, bit 9", HFILL }},
19083
19084                 { &hf_access_specific_8,
19085                   { "Specific access, bit 8", "nt.access_mask.specific_8",
19086                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19087                     0x0100, "Specific access, bit 8", HFILL }},
19088
19089                 { &hf_access_specific_7,
19090                   { "Specific access, bit 7", "nt.access_mask.specific_7",
19091                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19092                     0x0080, "Specific access, bit 7", HFILL }},
19093
19094                 { &hf_access_specific_6,
19095                   { "Specific access, bit 6", "nt.access_mask.specific_6",
19096                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19097                     0x0040, "Specific access, bit 6", HFILL }},
19098
19099                 { &hf_access_specific_5,
19100                   { "Specific access, bit 5", "nt.access_mask.specific_5",
19101                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19102                     0x0020, "Specific access, bit 5", HFILL }},
19103
19104                 { &hf_access_specific_4,
19105                   { "Specific access, bit 4", "nt.access_mask.specific_4",
19106                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19107                     0x0010, "Specific access, bit 4", HFILL }},
19108
19109                 { &hf_access_specific_3,
19110                   { "Specific access, bit 3", "nt.access_mask.specific_3",
19111                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19112                     0x0008, "Specific access, bit 3", HFILL }},
19113
19114                 { &hf_access_specific_2,
19115                   { "Specific access, bit 2", "nt.access_mask.specific_2",
19116                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19117                     0x0004, "Specific access, bit 2", HFILL }},
19118
19119                 { &hf_access_specific_1,
19120                   { "Specific access, bit 1", "nt.access_mask.specific_1",
19121                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19122                     0x0002, "Specific access, bit 1", HFILL }},
19123
19124                 { &hf_access_specific_0,
19125                   { "Specific access, bit 0", "nt.access_mask.specific_0",
19126                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19127                     0x0001, "Specific access, bit 0", HFILL }}
19128         };
19129
19130         static gint *ett[] = {
19131                 &ett_smb,
19132                 &ett_smb_hdr,
19133                 &ett_smb_command,
19134                 &ett_smb_fileattributes,
19135                 &ett_smb_capabilities,
19136                 &ett_smb_aflags,
19137                 &ett_smb_dialect,
19138                 &ett_smb_dialects,
19139                 &ett_smb_mode,
19140                 &ett_smb_rawmode,
19141                 &ett_smb_flags,
19142                 &ett_smb_flags2,
19143                 &ett_smb_desiredaccess,
19144                 &ett_smb_search,
19145                 &ett_smb_file,
19146                 &ett_smb_openfunction,
19147                 &ett_smb_filetype,
19148                 &ett_smb_openaction,
19149                 &ett_smb_writemode,
19150                 &ett_smb_lock_type,
19151                 &ett_smb_ssetupandxaction,
19152                 &ett_smb_optionsup,
19153                 &ett_smb_time_date,
19154                 &ett_smb_move_copy_flags,
19155                 &ett_smb_file_attributes,
19156                 &ett_smb_search_resume_key,
19157                 &ett_smb_search_dir_info,
19158                 &ett_smb_unlocks,
19159                 &ett_smb_unlock,
19160                 &ett_smb_locks,
19161                 &ett_smb_lock,
19162                 &ett_smb_open_flags,
19163                 &ett_smb_ipc_state,
19164                 &ett_smb_open_action,
19165                 &ett_smb_setup_action,
19166                 &ett_smb_connect_flags,
19167                 &ett_smb_connect_support_bits,
19168                 &ett_smb_nt_access_mask,
19169                 &ett_smb_nt_create_bits,
19170                 &ett_smb_nt_create_options,
19171                 &ett_smb_nt_share_access,
19172                 &ett_smb_nt_security_flags,
19173                 &ett_smb_nt_trans_setup,
19174                 &ett_smb_nt_trans_data,
19175                 &ett_smb_nt_trans_param,
19176                 &ett_smb_nt_notify_completion_filter,
19177                 &ett_smb_nt_ioctl_flags,
19178                 &ett_smb_security_information_mask,
19179                 &ett_smb_print_queue_entry,
19180                 &ett_smb_transaction_flags,
19181                 &ett_smb_transaction_params,
19182                 &ett_smb_find_first2_flags,
19183 #if 0
19184                 &ett_smb_ioflag,
19185 #endif
19186                 &ett_smb_transaction_data,
19187                 &ett_smb_stream_info,
19188                 &ett_smb_dfs_referrals,
19189                 &ett_smb_dfs_referral,
19190                 &ett_smb_dfs_referral_flags,
19191                 &ett_smb_get_dfs_flags,
19192                 &ett_smb_ff2_data,
19193                 &ett_smb_device_characteristics,
19194                 &ett_smb_fs_attributes,
19195                 &ett_smb_segments,
19196                 &ett_smb_segment,
19197                 &ett_smb_sec_desc,
19198                 &ett_smb_sid,
19199                 &ett_smb_acl,
19200                 &ett_smb_ace,
19201                 &ett_smb_ace_flags,
19202                 &ett_smb_sec_desc_type,
19203                 &ett_smb_quotaflags,
19204                 &ett_smb_secblob,
19205                 &ett_smb_mac_support_flags,
19206                 &ett_nt_access_mask,
19207                 &ett_nt_access_mask_generic,
19208                 &ett_nt_access_mask_standard,
19209                 &ett_nt_access_mask_specific,
19210                 &ett_smb_unicode_password,
19211                 &ett_smb_ea,
19212                 &ett_smb_unix_capabilities
19213         };
19214         module_t *smb_module;
19215
19216         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
19217             "SMB", "smb");
19218         proto_register_subtree_array(ett, array_length(ett));
19219         proto_register_field_array(proto_smb, hf, array_length(hf));
19220
19221         register_smb_common(proto_smb);
19222
19223         register_init_routine(&smb_init_protocol);
19224         smb_module = prefs_register_protocol(proto_smb, NULL);
19225         prefs_register_bool_preference(smb_module, "trans_reassembly",
19226                 "Reassemble SMB Transaction payload",
19227                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
19228                 &smb_trans_reassembly);
19229         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
19230                 "Reassemble DCERPC over SMB",
19231                 "Whether the dissector should reassemble DCERPC over SMB commands",
19232                 &smb_dcerpc_reassembly);
19233         prefs_register_bool_preference(smb_module, "sid_name_snooping",
19234                 "Snoop SID to Name mappings",
19235                 "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
19236                 &sid_name_snooping);
19237
19238         register_init_routine(smb_trans_reassembly_init);
19239         smb_tap = register_tap("smb");
19240 }
19241
19242 void
19243 proto_reg_handoff_smb(void)
19244 {
19245         dissector_handle_t smb_handle;
19246
19247         gssapi_handle = find_dissector("gssapi");
19248         ntlmssp_handle = find_dissector("ntlmssp");
19249
19250         heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
19251         heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
19252         heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
19253         smb_handle = create_dissector_handle(dissect_smb, proto_smb);
19254         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
19255         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
19256         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER,
19257             smb_handle);
19258 }