Add a heuristic dissector table to Vines SPP, use it for dissecting SPP
[metze/wireshark/wip.git] / packet-smb.c
1 /* packet-smb.c
2  * Routines for smb packet dissection
3  * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
4  * 2001  Rewrite by Ronnie Sahlberg and Guy Harris
5  *
6  * $Id: packet-smb.c,v 1.330 2003/04/17 20:30:41 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/packet.h>
40 #include <epan/conversation.h>
41 #include "smb.h"
42 #include "alignment.h"
43 #include <epan/strutil.h>
44 #include "prefs.h"
45 #include "reassemble.h"
46 #include "tap.h"
47 #include "packet-ipx.h"
48
49 #include "packet-smb-common.h"
50 #include "packet-smb-mailslot.h"
51 #include "packet-smb-pipe.h"
52 #include "packet-dcerpc.h"
53 #include "packet-smb-sidsnooping.h"
54
55 /*
56  * Various specifications and documents about SMB can be found in
57  *
58  *      ftp://ftp.microsoft.com/developr/drg/CIFS/
59  *
60  * and a CIFS specification from the Storage Networking Industry Association
61  * can be found on a link from the page at
62  *
63  *      http://www.snia.org/tech_activities/CIFS
64  *
65  * (it supercedes the document at
66  *
67  *      ftp://ftp.microsoft.com/developr/drg/CIFS/draft-leach-cifs-v1-spec-01.txt
68  *
69  * ).
70  *
71  * There are also some Open Group publications documenting CIFS available
72  * for download; catalog entries for them are at:
73  *
74  *      http://www.opengroup.org/products/publications/catalog/c209.htm
75  *
76  *      http://www.opengroup.org/products/publications/catalog/c195.htm
77  *
78  * The document "NT LAN Manager SMB File Sharing Protocol Extensions"
79  * can be found at
80  *
81  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
82  *
83  * (or, presumably a similar path under the Samba mirrors).  As the
84  * ".doc" indicates, it's a Word document.  Some of the specs from the
85  * Microsoft FTP site can be found in the
86  *
87  *      http://www.samba.org/samba/ftp/specs/
88  *
89  * directory as well.
90  *
91  * Beware - these specs may have errors.
92  */
93 static int proto_smb = -1;
94 static int hf_smb_cmd = -1;
95 static int hf_smb_key = -1;
96 static int hf_smb_session_id = -1;
97 static int hf_smb_sequence_num = -1;
98 static int hf_smb_group_id = -1;
99 static int hf_smb_pid = -1;
100 static int hf_smb_tid = -1;
101 static int hf_smb_uid = -1;
102 static int hf_smb_mid = -1;
103 static int hf_smb_response_to = -1;
104 static int hf_smb_time = -1;
105 static int hf_smb_response_in = -1;
106 static int hf_smb_continuation_to = -1;
107 static int hf_smb_nt_status = -1;
108 static int hf_smb_error_class = -1;
109 static int hf_smb_error_code = -1;
110 static int hf_smb_reserved = -1;
111 static int hf_smb_flags_lock = -1;
112 static int hf_smb_flags_receive_buffer = -1;
113 static int hf_smb_flags_caseless = -1;
114 static int hf_smb_flags_canon = -1;
115 static int hf_smb_flags_oplock = -1;
116 static int hf_smb_flags_notify = -1;
117 static int hf_smb_flags_response = -1;
118 static int hf_smb_flags2_long_names_allowed = -1;
119 static int hf_smb_flags2_ea = -1;
120 static int hf_smb_flags2_sec_sig = -1;
121 static int hf_smb_flags2_long_names_used = -1;
122 static int hf_smb_flags2_esn = -1;
123 static int hf_smb_flags2_dfs = -1;
124 static int hf_smb_flags2_roe = -1;
125 static int hf_smb_flags2_nt_error = -1;
126 static int hf_smb_flags2_string = -1;
127 static int hf_smb_word_count = -1;
128 static int hf_smb_byte_count = -1;
129 static int hf_smb_buffer_format = -1;
130 static int hf_smb_dialect_name = -1;
131 static int hf_smb_dialect_index = -1;
132 static int hf_smb_max_trans_buf_size = -1;
133 static int hf_smb_max_mpx_count = -1;
134 static int hf_smb_max_vcs_num = -1;
135 static int hf_smb_session_key = -1;
136 static int hf_smb_server_timezone = -1;
137 static int hf_smb_encryption_key_length = -1;
138 static int hf_smb_encryption_key = -1;
139 static int hf_smb_primary_domain = -1;
140 static int hf_smb_server = -1;
141 static int hf_smb_max_raw_buf_size = -1;
142 static int hf_smb_server_guid = -1;
143 static int hf_smb_security_blob_len = -1;
144 static int hf_smb_security_blob = -1;
145 static int hf_smb_sm_mode16 = -1;
146 static int hf_smb_sm_password16 = -1;
147 static int hf_smb_sm_mode = -1;
148 static int hf_smb_sm_password = -1;
149 static int hf_smb_sm_signatures = -1;
150 static int hf_smb_sm_sig_required = -1;
151 static int hf_smb_rm_read = -1;
152 static int hf_smb_rm_write = -1;
153 static int hf_smb_server_date_time = -1;
154 static int hf_smb_server_smb_date = -1;
155 static int hf_smb_server_smb_time = -1;
156 static int hf_smb_server_cap_raw_mode = -1;
157 static int hf_smb_server_cap_mpx_mode = -1;
158 static int hf_smb_server_cap_unicode = -1;
159 static int hf_smb_server_cap_large_files = -1;
160 static int hf_smb_server_cap_nt_smbs = -1;
161 static int hf_smb_server_cap_rpc_remote_apis = -1;
162 static int hf_smb_server_cap_nt_status = -1;
163 static int hf_smb_server_cap_level_ii_oplocks = -1;
164 static int hf_smb_server_cap_lock_and_read = -1;
165 static int hf_smb_server_cap_nt_find = -1;
166 static int hf_smb_server_cap_dfs = -1;
167 static int hf_smb_server_cap_infolevel_passthru = -1;
168 static int hf_smb_server_cap_large_readx = -1;
169 static int hf_smb_server_cap_large_writex = -1;
170 static int hf_smb_server_cap_unix = -1;
171 static int hf_smb_server_cap_reserved = -1;
172 static int hf_smb_server_cap_bulk_transfer = -1;
173 static int hf_smb_server_cap_compressed_data = -1;
174 static int hf_smb_server_cap_extended_security = -1;
175 static int hf_smb_system_time = -1;
176 static int hf_smb_unknown = -1;
177 static int hf_smb_dir_name = -1;
178 static int hf_smb_echo_count = -1;
179 static int hf_smb_echo_data = -1;
180 static int hf_smb_echo_seq_num = -1;
181 static int hf_smb_max_buf_size = -1;
182 static int hf_smb_password = -1;
183 static int hf_smb_password_len = -1;
184 static int hf_smb_ansi_password = -1;
185 static int hf_smb_ansi_password_len = -1;
186 static int hf_smb_unicode_password = -1;
187 static int hf_smb_unicode_password_len = -1;
188 static int hf_smb_path = -1;
189 static int hf_smb_service = -1;
190 static int hf_smb_move_flags_file = -1;
191 static int hf_smb_move_flags_dir = -1;
192 static int hf_smb_move_flags_verify = -1;
193 static int hf_smb_files_moved = -1;
194 static int hf_smb_copy_flags_file = -1;
195 static int hf_smb_copy_flags_dir = -1;
196 static int hf_smb_copy_flags_dest_mode = -1;
197 static int hf_smb_copy_flags_source_mode = -1;
198 static int hf_smb_copy_flags_verify = -1;
199 static int hf_smb_copy_flags_tree_copy = -1;
200 static int hf_smb_copy_flags_ea_action = -1;
201 static int hf_smb_count = -1;
202 static int hf_smb_file_name = -1;
203 static int hf_smb_open_function_open = -1;
204 static int hf_smb_open_function_create = -1;
205 static int hf_smb_fid = -1;
206 static int hf_smb_file_attr_read_only_16bit = -1;
207 static int hf_smb_file_attr_read_only_8bit = -1;
208 static int hf_smb_file_attr_hidden_16bit = -1;
209 static int hf_smb_file_attr_hidden_8bit = -1;
210 static int hf_smb_file_attr_system_16bit = -1;
211 static int hf_smb_file_attr_system_8bit = -1;
212 static int hf_smb_file_attr_volume_16bit = -1;
213 static int hf_smb_file_attr_volume_8bit = -1;
214 static int hf_smb_file_attr_directory_16bit = -1;
215 static int hf_smb_file_attr_directory_8bit = -1;
216 static int hf_smb_file_attr_archive_16bit = -1;
217 static int hf_smb_file_attr_archive_8bit = -1;
218 static int hf_smb_file_attr_device = -1;
219 static int hf_smb_file_attr_normal = -1;
220 static int hf_smb_file_attr_temporary = -1;
221 static int hf_smb_file_attr_sparse = -1;
222 static int hf_smb_file_attr_reparse = -1;
223 static int hf_smb_file_attr_compressed = -1;
224 static int hf_smb_file_attr_offline = -1;
225 static int hf_smb_file_attr_not_content_indexed = -1;
226 static int hf_smb_file_attr_encrypted = -1;
227 static int hf_smb_file_size = -1;
228 static int hf_smb_search_attribute_read_only = -1;
229 static int hf_smb_search_attribute_hidden = -1;
230 static int hf_smb_search_attribute_system = -1;
231 static int hf_smb_search_attribute_volume = -1;
232 static int hf_smb_search_attribute_directory = -1;
233 static int hf_smb_search_attribute_archive = -1;
234 static int hf_smb_access_mode = -1;
235 static int hf_smb_access_sharing = -1;
236 static int hf_smb_access_locality = -1;
237 static int hf_smb_access_caching = -1;
238 static int hf_smb_access_writetru = -1;
239 static int hf_smb_create_time = -1;
240 static int hf_smb_modify_time = -1;
241 static int hf_smb_backup_time = -1;
242 static int hf_smb_mac_alloc_block_count = -1;
243 static int hf_smb_mac_alloc_block_size = -1;
244 static int hf_smb_mac_free_block_count = -1;
245 static int hf_smb_mac_fndrinfo = -1;
246 static int hf_smb_mac_root_file_count = -1;
247 static int hf_smb_mac_root_dir_count = -1;
248 static int hf_smb_mac_file_count = -1;
249 static int hf_smb_mac_dir_count = -1;
250 static int hf_smb_mac_support_flags = -1;
251 static int hf_smb_mac_sup_access_ctrl = -1;
252 static int hf_smb_mac_sup_getset_comments = -1;
253 static int hf_smb_mac_sup_desktopdb_calls = -1;
254 static int hf_smb_mac_sup_unique_ids = -1;
255 static int hf_smb_mac_sup_streams = -1;
256 static int hf_smb_create_dos_date = -1;
257 static int hf_smb_create_dos_time = -1;
258 static int hf_smb_last_write_time = -1;
259 static int hf_smb_last_write_dos_date = -1;
260 static int hf_smb_last_write_dos_time = -1;
261 static int hf_smb_access_time = -1;
262 static int hf_smb_access_dos_date = -1;
263 static int hf_smb_access_dos_time = -1;
264 static int hf_smb_old_file_name = -1;
265 static int hf_smb_offset = -1;
266 static int hf_smb_remaining = -1;
267 static int hf_smb_padding = -1;
268 static int hf_smb_file_data = -1;
269 static int hf_smb_total_data_len = -1;
270 static int hf_smb_data_len = -1;
271 static int hf_smb_seek_mode = -1;
272 static int hf_smb_data_size = -1;
273 static int hf_smb_alloc_size = -1;
274 static int hf_smb_alloc_size64 = -1;
275 static int hf_smb_max_count = -1;
276 static int hf_smb_min_count = -1;
277 static int hf_smb_timeout = -1;
278 static int hf_smb_high_offset = -1;
279 static int hf_smb_units = -1;
280 static int hf_smb_bpu = -1;
281 static int hf_smb_blocksize = -1;
282 static int hf_smb_freeunits = -1;
283 static int hf_smb_data_offset = -1;
284 static int hf_smb_dcm = -1;
285 static int hf_smb_request_mask = -1;
286 static int hf_smb_response_mask = -1;
287 static int hf_smb_search_id = -1;
288 static int hf_smb_write_mode_write_through = -1;
289 static int hf_smb_write_mode_return_remaining = -1;
290 static int hf_smb_write_mode_raw = -1;
291 static int hf_smb_write_mode_message_start = -1;
292 static int hf_smb_write_mode_connectionless = -1;
293 static int hf_smb_resume_key_len = -1;
294 static int hf_smb_resume_find_id = -1;
295 static int hf_smb_resume_server_cookie = -1;
296 static int hf_smb_resume_client_cookie = -1;
297 static int hf_smb_andxoffset = -1;
298 static int hf_smb_lock_type_large = -1;
299 static int hf_smb_lock_type_cancel = -1;
300 static int hf_smb_lock_type_change = -1;
301 static int hf_smb_lock_type_oplock = -1;
302 static int hf_smb_lock_type_shared = -1;
303 static int hf_smb_locking_ol = -1;
304 static int hf_smb_number_of_locks = -1;
305 static int hf_smb_number_of_unlocks = -1;
306 static int hf_smb_lock_long_offset = -1;
307 static int hf_smb_lock_long_length = -1;
308 static int hf_smb_file_type = -1;
309 static int hf_smb_ipc_state_nonblocking = -1;
310 static int hf_smb_ipc_state_endpoint = -1;
311 static int hf_smb_ipc_state_pipe_type = -1;
312 static int hf_smb_ipc_state_read_mode = -1;
313 static int hf_smb_ipc_state_icount = -1;
314 static int hf_smb_server_fid = -1;
315 static int hf_smb_open_flags_add_info = -1;
316 static int hf_smb_open_flags_ex_oplock = -1;
317 static int hf_smb_open_flags_batch_oplock = -1;
318 static int hf_smb_open_flags_ealen = -1;
319 static int hf_smb_open_action_open = -1;
320 static int hf_smb_open_action_lock = -1;
321 static int hf_smb_vc_num = -1;
322 static int hf_smb_account = -1;
323 static int hf_smb_os = -1;
324 static int hf_smb_lanman = -1;
325 static int hf_smb_setup_action_guest = -1;
326 static int hf_smb_fs = -1;
327 static int hf_smb_connect_flags_dtid = -1;
328 static int hf_smb_connect_support_search = -1;
329 static int hf_smb_connect_support_in_dfs = -1;
330 static int hf_smb_max_setup_count = -1;
331 static int hf_smb_total_param_count = -1;
332 static int hf_smb_total_data_count = -1;
333 static int hf_smb_max_param_count = -1;
334 static int hf_smb_max_data_count = -1;
335 static int hf_smb_param_disp16 = -1;
336 static int hf_smb_param_count16 = -1;
337 static int hf_smb_param_offset16 = -1;
338 static int hf_smb_param_disp32 = -1;
339 static int hf_smb_param_count32 = -1;
340 static int hf_smb_param_offset32 = -1;
341 static int hf_smb_data_disp16 = -1;
342 static int hf_smb_data_count16 = -1;
343 static int hf_smb_data_offset16 = -1;
344 static int hf_smb_data_disp32 = -1;
345 static int hf_smb_data_count32 = -1;
346 static int hf_smb_data_offset32 = -1;
347 static int hf_smb_setup_count = -1;
348 static int hf_smb_nt_trans_subcmd = -1;
349 static int hf_smb_nt_ioctl_function_code = -1;
350 static int hf_smb_nt_ioctl_isfsctl = -1;
351 static int hf_smb_nt_ioctl_flags_root_handle = -1;
352 static int hf_smb_nt_ioctl_data = -1;
353 #ifdef SMB_UNUSED_HANDLES
354 static int hf_smb_nt_security_information = -1;
355 #endif
356 static int hf_smb_nt_notify_action = -1;
357 static int hf_smb_nt_notify_watch_tree = -1;
358 static int hf_smb_nt_notify_stream_write = -1;
359 static int hf_smb_nt_notify_stream_size = -1;
360 static int hf_smb_nt_notify_stream_name = -1;
361 static int hf_smb_nt_notify_security = -1;
362 static int hf_smb_nt_notify_ea = -1;
363 static int hf_smb_nt_notify_creation = -1;
364 static int hf_smb_nt_notify_last_access = -1;
365 static int hf_smb_nt_notify_last_write = -1;
366 static int hf_smb_nt_notify_size = -1;
367 static int hf_smb_nt_notify_attributes = -1;
368 static int hf_smb_nt_notify_dir_name = -1;
369 static int hf_smb_nt_notify_file_name = -1;
370 static int hf_smb_root_dir_fid = -1;
371 static int hf_smb_nt_create_disposition = -1;
372 static int hf_smb_sd_length = -1;
373 static int hf_smb_ea_length = -1;
374 static int hf_smb_file_name_len = -1;
375 static int hf_smb_nt_impersonation_level = -1;
376 static int hf_smb_nt_security_flags_context_tracking = -1;
377 static int hf_smb_nt_security_flags_effective_only = -1;
378 static int hf_smb_nt_access_mask_generic_read = -1;
379 static int hf_smb_nt_access_mask_generic_write = -1;
380 static int hf_smb_nt_access_mask_generic_execute = -1;
381 static int hf_smb_nt_access_mask_generic_all = -1;
382 static int hf_smb_nt_access_mask_maximum_allowed = -1;
383 static int hf_smb_nt_access_mask_system_security = -1;
384 static int hf_smb_nt_access_mask_synchronize = -1;
385 static int hf_smb_nt_access_mask_write_owner = -1;
386 static int hf_smb_nt_access_mask_write_dac = -1;
387 static int hf_smb_nt_access_mask_read_control = -1;
388 static int hf_smb_nt_access_mask_delete = -1;
389 static int hf_smb_nt_access_mask_write_attributes = -1;
390 static int hf_smb_nt_access_mask_read_attributes = -1;
391 static int hf_smb_nt_access_mask_delete_child = -1;
392 static int hf_smb_nt_access_mask_execute = -1;
393 static int hf_smb_nt_access_mask_write_ea = -1;
394 static int hf_smb_nt_access_mask_read_ea = -1;
395 static int hf_smb_nt_access_mask_append = -1;
396 static int hf_smb_nt_access_mask_write = -1;
397 static int hf_smb_nt_access_mask_read = -1;
398 static int hf_smb_nt_create_bits_oplock = -1;
399 static int hf_smb_nt_create_bits_boplock = -1;
400 static int hf_smb_nt_create_bits_dir = -1;
401 static int hf_smb_nt_create_options_directory_file = -1;
402 static int hf_smb_nt_create_options_write_through = -1;
403 static int hf_smb_nt_create_options_sequential_only = -1;
404 static int hf_smb_nt_create_options_sync_io_alert = -1;
405 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
406 static int hf_smb_nt_create_options_non_directory_file = -1;
407 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
408 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
409 static int hf_smb_nt_create_options_random_access = -1;
410 static int hf_smb_nt_create_options_delete_on_close = -1;
411 static int hf_smb_nt_share_access_read = -1;
412 static int hf_smb_nt_share_access_write = -1;
413 static int hf_smb_nt_share_access_delete = -1;
414 static int hf_smb_file_eattr_read_only = -1;
415 static int hf_smb_file_eattr_hidden = -1;
416 static int hf_smb_file_eattr_system = -1;
417 static int hf_smb_file_eattr_volume = -1;
418 static int hf_smb_file_eattr_directory = -1;
419 static int hf_smb_file_eattr_archive = -1;
420 static int hf_smb_file_eattr_device = -1;
421 static int hf_smb_file_eattr_normal = -1;
422 static int hf_smb_file_eattr_temporary = -1;
423 static int hf_smb_file_eattr_sparse = -1;
424 static int hf_smb_file_eattr_reparse = -1;
425 static int hf_smb_file_eattr_compressed = -1;
426 static int hf_smb_file_eattr_offline = -1;
427 static int hf_smb_file_eattr_not_content_indexed = -1;
428 static int hf_smb_file_eattr_encrypted = -1;
429 static int hf_smb_sec_desc_len = -1;
430 static int hf_smb_sec_desc_revision = -1;
431 static int hf_smb_sec_desc_type_owner_defaulted = -1;
432 static int hf_smb_sec_desc_type_group_defaulted = -1;
433 static int hf_smb_sec_desc_type_dacl_present = -1;
434 static int hf_smb_sec_desc_type_dacl_defaulted = -1;
435 static int hf_smb_sec_desc_type_sacl_present = -1;
436 static int hf_smb_sec_desc_type_sacl_defaulted = -1;
437 static int hf_smb_sec_desc_type_dacl_auto_inherit_req = -1;
438 static int hf_smb_sec_desc_type_sacl_auto_inherit_req = -1;
439 static int hf_smb_sec_desc_type_dacl_auto_inherited = -1;
440 static int hf_smb_sec_desc_type_sacl_auto_inherited = -1;
441 static int hf_smb_sec_desc_type_dacl_protected = -1;
442 static int hf_smb_sec_desc_type_sacl_protected = -1;
443 static int hf_smb_sec_desc_type_self_relative = -1;
444 static int hf_smb_sid = -1;
445 static int hf_smb_sid_revision = -1;
446 static int hf_smb_sid_num_auth = -1;
447 static int hf_smb_acl_revision = -1;
448 static int hf_smb_acl_size = -1;
449 static int hf_smb_acl_num_aces = -1;
450 static int hf_smb_ace_type = -1;
451 static int hf_smb_ace_size = -1;
452 static int hf_smb_ace_flags_object_inherit = -1;
453 static int hf_smb_ace_flags_container_inherit = -1;
454 static int hf_smb_ace_flags_non_propagate_inherit = -1;
455 static int hf_smb_ace_flags_inherit_only = -1;
456 static int hf_smb_ace_flags_inherited_ace = -1;
457 static int hf_smb_ace_flags_successful_access = -1;
458 static int hf_smb_ace_flags_failed_access = -1;
459 static int hf_smb_nt_qsd_owner = -1;
460 static int hf_smb_nt_qsd_group = -1;
461 static int hf_smb_nt_qsd_dacl = -1;
462 static int hf_smb_nt_qsd_sacl = -1;
463 static int hf_smb_extended_attributes = -1;
464 static int hf_smb_oplock_level = -1;
465 static int hf_smb_create_action = -1;
466 static int hf_smb_file_id = -1;
467 static int hf_smb_ea_error_offset = -1;
468 static int hf_smb_end_of_file = -1;
469 static int hf_smb_device_type = -1;
470 static int hf_smb_is_directory = -1;
471 static int hf_smb_next_entry_offset = -1;
472 static int hf_smb_change_time = -1;
473 static int hf_smb_setup_len = -1;
474 static int hf_smb_print_mode = -1;
475 static int hf_smb_print_identifier = -1;
476 static int hf_smb_restart_index = -1;
477 static int hf_smb_print_queue_date = -1;
478 static int hf_smb_print_queue_dos_date = -1;
479 static int hf_smb_print_queue_dos_time = -1;
480 static int hf_smb_print_status = -1;
481 static int hf_smb_print_spool_file_number = -1;
482 static int hf_smb_print_spool_file_size = -1;
483 static int hf_smb_print_spool_file_name = -1;
484 static int hf_smb_start_index = -1;
485 static int hf_smb_originator_name = -1;
486 static int hf_smb_destination_name = -1;
487 static int hf_smb_message_len = -1;
488 static int hf_smb_message = -1;
489 static int hf_smb_mgid = -1;
490 static int hf_smb_forwarded_name = -1;
491 static int hf_smb_machine_name = -1;
492 static int hf_smb_cancel_to = -1;
493 static int hf_smb_trans2_subcmd = -1;
494 static int hf_smb_trans_name = -1;
495 static int hf_smb_transaction_flags_dtid = -1;
496 static int hf_smb_transaction_flags_owt = -1;
497 static int hf_smb_search_count = -1;
498 static int hf_smb_search_pattern = -1;
499 static int hf_smb_ff2_backup = -1;
500 static int hf_smb_ff2_continue = -1;
501 static int hf_smb_ff2_resume = -1;
502 static int hf_smb_ff2_close_eos = -1;
503 static int hf_smb_ff2_close = -1;
504 static int hf_smb_ff2_information_level = -1;
505 static int hf_smb_qpi_loi = -1;
506 #if 0
507 static int hf_smb_sfi_writetru = -1;
508 static int hf_smb_sfi_caching = -1;
509 #endif
510 static int hf_smb_storage_type = -1;
511 static int hf_smb_resume = -1;
512 static int hf_smb_max_referral_level = -1;
513 static int hf_smb_qfsi_information_level = -1;
514 static int hf_smb_ea_size = -1;
515 static int hf_smb_list_length = -1;
516 static int hf_smb_number_of_links = -1;
517 static int hf_smb_delete_pending = -1;
518 static int hf_smb_index_number = -1;
519 static int hf_smb_current_offset = -1;
520 static int hf_smb_t2_alignment = -1;
521 static int hf_smb_t2_stream_name_length = -1;
522 static int hf_smb_t2_stream_size = -1;
523 static int hf_smb_t2_stream_name = -1;
524 static int hf_smb_t2_compressed_file_size = -1;
525 static int hf_smb_t2_compressed_format = -1;
526 static int hf_smb_t2_compressed_unit_shift = -1;
527 static int hf_smb_t2_compressed_chunk_shift = -1;
528 static int hf_smb_t2_compressed_cluster_shift = -1;
529 static int hf_smb_dfs_path_consumed = -1;
530 static int hf_smb_dfs_num_referrals = -1;
531 static int hf_smb_get_dfs_server_hold_storage = -1;
532 static int hf_smb_get_dfs_fielding = -1;
533 static int hf_smb_dfs_referral_version = -1;
534 static int hf_smb_dfs_referral_size = -1;
535 static int hf_smb_dfs_referral_server_type = -1;
536 static int hf_smb_dfs_referral_flags_strip = -1;
537 static int hf_smb_dfs_referral_node_offset = -1;
538 static int hf_smb_dfs_referral_node = -1;
539 static int hf_smb_dfs_referral_proximity = -1;
540 static int hf_smb_dfs_referral_ttl = -1;
541 static int hf_smb_dfs_referral_path_offset = -1;
542 static int hf_smb_dfs_referral_path = -1;
543 static int hf_smb_dfs_referral_alt_path_offset = -1;
544 static int hf_smb_dfs_referral_alt_path = -1;
545 static int hf_smb_end_of_search = -1;
546 static int hf_smb_last_name_offset = -1;
547 static int hf_smb_fn_information_level = -1;
548 static int hf_smb_monitor_handle = -1;
549 static int hf_smb_change_count = -1;
550 static int hf_smb_file_index = -1;
551 static int hf_smb_short_file_name = -1;
552 static int hf_smb_short_file_name_len = -1;
553 static int hf_smb_fs_id = -1;
554 static int hf_smb_sector_unit = -1;
555 static int hf_smb_fs_units = -1;
556 static int hf_smb_fs_sector = -1;
557 static int hf_smb_avail_units = -1;
558 static int hf_smb_volume_serial_num = -1;
559 static int hf_smb_volume_label_len = -1;
560 static int hf_smb_volume_label = -1;
561 static int hf_smb_free_alloc_units64 = -1;
562 static int hf_smb_caller_free_alloc_units64 = -1;
563 static int hf_smb_actual_free_alloc_units64 = -1;
564 static int hf_smb_max_name_len = -1;
565 static int hf_smb_fs_name_len = -1;
566 static int hf_smb_fs_name = -1;
567 static int hf_smb_device_char_removable = -1;
568 static int hf_smb_device_char_read_only = -1;
569 static int hf_smb_device_char_floppy = -1;
570 static int hf_smb_device_char_write_once = -1;
571 static int hf_smb_device_char_remote = -1;
572 static int hf_smb_device_char_mounted = -1;
573 static int hf_smb_device_char_virtual = -1;
574 static int hf_smb_fs_attr_css = -1;
575 static int hf_smb_fs_attr_cpn = -1;
576 static int hf_smb_fs_attr_pacls = -1;
577 static int hf_smb_fs_attr_fc = -1;
578 static int hf_smb_fs_attr_vq = -1;
579 static int hf_smb_fs_attr_dim = -1;
580 static int hf_smb_fs_attr_vic = -1;
581 static int hf_smb_quota_flags_enabled = -1;
582 static int hf_smb_quota_flags_deny_disk = -1;
583 static int hf_smb_quota_flags_log_limit = -1;
584 static int hf_smb_quota_flags_log_warning = -1;
585 static int hf_smb_soft_quota_limit = -1;
586 static int hf_smb_hard_quota_limit = -1;
587 static int hf_smb_user_quota_used = -1;
588 static int hf_smb_user_quota_offset = -1;
589 static int hf_smb_nt_rename_level = -1;
590 static int hf_smb_cluster_count = -1;
591 static int hf_smb_segments = -1;
592 static int hf_smb_segment = -1;
593 static int hf_smb_segment_overlap = -1;
594 static int hf_smb_segment_overlap_conflict = -1;
595 static int hf_smb_segment_multiple_tails = -1;
596 static int hf_smb_segment_too_long_fragment = -1;
597 static int hf_smb_segment_error = -1;
598 static int hf_smb_pipe_write_len = -1;
599
600 static gint ett_smb = -1;
601 static gint ett_smb_hdr = -1;
602 static gint ett_smb_command = -1;
603 static gint ett_smb_fileattributes = -1;
604 static gint ett_smb_capabilities = -1;
605 static gint ett_smb_aflags = -1;
606 static gint ett_smb_dialect = -1;
607 static gint ett_smb_dialects = -1;
608 static gint ett_smb_mode = -1;
609 static gint ett_smb_rawmode = -1;
610 static gint ett_smb_flags = -1;
611 static gint ett_smb_flags2 = -1;
612 static gint ett_smb_desiredaccess = -1;
613 static gint ett_smb_search = -1;
614 static gint ett_smb_file = -1;
615 static gint ett_smb_openfunction = -1;
616 static gint ett_smb_filetype = -1;
617 static gint ett_smb_openaction = -1;
618 static gint ett_smb_writemode = -1;
619 static gint ett_smb_lock_type = -1;
620 static gint ett_smb_ssetupandxaction = -1;
621 static gint ett_smb_optionsup = -1;
622 static gint ett_smb_time_date = -1;
623 static gint ett_smb_move_copy_flags = -1;
624 static gint ett_smb_file_attributes = -1;
625 static gint ett_smb_search_resume_key = -1;
626 static gint ett_smb_search_dir_info = -1;
627 static gint ett_smb_unlocks = -1;
628 static gint ett_smb_unlock = -1;
629 static gint ett_smb_locks = -1;
630 static gint ett_smb_lock = -1;
631 static gint ett_smb_open_flags = -1;
632 static gint ett_smb_ipc_state = -1;
633 static gint ett_smb_open_action = -1;
634 static gint ett_smb_setup_action = -1;
635 static gint ett_smb_connect_flags = -1;
636 static gint ett_smb_connect_support_bits = -1;
637 static gint ett_smb_nt_access_mask = -1;
638 static gint ett_smb_nt_create_bits = -1;
639 static gint ett_smb_nt_create_options = -1;
640 static gint ett_smb_nt_share_access = -1;
641 static gint ett_smb_nt_security_flags = -1;
642 static gint ett_smb_nt_trans_setup = -1;
643 static gint ett_smb_nt_trans_data = -1;
644 static gint ett_smb_nt_trans_param = -1;
645 static gint ett_smb_nt_notify_completion_filter = -1;
646 static gint ett_smb_nt_ioctl_flags = -1;
647 static gint ett_smb_security_information_mask = -1;
648 static gint ett_smb_print_queue_entry = -1;
649 static gint ett_smb_transaction_flags = -1;
650 static gint ett_smb_transaction_params = -1;
651 static gint ett_smb_find_first2_flags = -1;
652 static gint ett_smb_mac_support_flags = -1;
653 #if 0
654 static gint ett_smb_ioflag = -1;
655 #endif
656 static gint ett_smb_transaction_data = -1;
657 static gint ett_smb_stream_info = -1;
658 static gint ett_smb_dfs_referrals = -1;
659 static gint ett_smb_dfs_referral = -1;
660 static gint ett_smb_dfs_referral_flags = -1;
661 static gint ett_smb_get_dfs_flags = -1;
662 static gint ett_smb_ff2_data = -1;
663 static gint ett_smb_device_characteristics = -1;
664 static gint ett_smb_fs_attributes = -1;
665 static gint ett_smb_segments = -1;
666 static gint ett_smb_segment = -1;
667 static gint ett_smb_sec_desc = -1;
668 static gint ett_smb_sid = -1;
669 static gint ett_smb_acl = -1;
670 static gint ett_smb_ace = -1;
671 static gint ett_smb_ace_flags = -1;
672 static gint ett_smb_sec_desc_type = -1;
673 static gint ett_smb_quotaflags = -1;
674 static gint ett_smb_secblob = -1;
675
676
677 static int smb_tap = -1;
678
679 static dissector_handle_t gssapi_handle = NULL;
680 static dissector_handle_t ntlmssp_handle = NULL;
681
682 static const fragment_items smb_frag_items = {
683         &ett_smb_segment,
684         &ett_smb_segments,
685
686         &hf_smb_segments,
687         &hf_smb_segment,
688         &hf_smb_segment_overlap,
689         &hf_smb_segment_overlap_conflict,
690         &hf_smb_segment_multiple_tails,
691         &hf_smb_segment_too_long_fragment,
692         &hf_smb_segment_error,
693
694         "segments"
695 };
696
697 proto_tree *top_tree=NULL;     /* ugly */
698
699 static char *decode_smb_name(unsigned char);
700 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu);
701
702 /*
703  * Macros for use in the main dissector routines for an SMB.
704  */
705
706 #define WORD_COUNT      \
707         /* Word Count */                                \
708         wc = tvb_get_guint8(tvb, offset);               \
709         proto_tree_add_uint(tree, hf_smb_word_count,    \
710                 tvb, offset, 1, wc);                    \
711         offset += 1;                                    \
712         if(wc==0) goto bytecount;
713
714 #define BYTE_COUNT      \
715         bytecount:                                      \
716         bc = tvb_get_letohs(tvb, offset);               \
717         proto_tree_add_uint(tree, hf_smb_byte_count,    \
718                         tvb, offset, 2, bc);            \
719         offset += 2;                                    \
720         if(bc==0) goto endofcommand;
721
722 #define CHECK_BYTE_COUNT(len)   \
723         if (bc < len) goto endofcommand;
724
725 #define COUNT_BYTES(len)   {\
726         int tmp;            \
727         tmp=len;            \
728         offset += tmp;      \
729         bc -= tmp;          \
730         }
731
732 #define END_OF_SMB      \
733         if (bc != 0) { \
734                 proto_tree_add_text(tree, tvb, offset, bc, \
735                     "Extra byte parameters");           \
736                 offset += bc;                           \
737         }                                               \
738         endofcommand:
739
740 /*
741  * Macros for use in routines called by them.
742  */
743 #define CHECK_BYTE_COUNT_SUBR(len)      \
744         if (*bcp < len) {               \
745                 *trunc = TRUE;          \
746                 return offset;          \
747         }
748
749 #define CHECK_STRING_SUBR(fn)   \
750         if (fn == NULL) {       \
751                 *trunc = TRUE;  \
752                 return offset;  \
753         }
754
755 #define COUNT_BYTES_SUBR(len)   \
756         offset += len;          \
757         *bcp -= len;
758
759 /*
760  * Macros for use when dissecting transaction parameters and data
761  */
762 #define CHECK_BYTE_COUNT_TRANS(len)     \
763         if (bc < len) return offset;
764
765 #define CHECK_STRING_TRANS(fn)  \
766         if (fn == NULL) return offset;
767
768 #define COUNT_BYTES_TRANS(len)  \
769         offset += len;          \
770         bc -= len;
771
772 /*
773  * Macros for use in subrroutines dissecting transaction parameters or data
774  */
775 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
776         if (*bcp < len) return offset;
777
778 #define CHECK_STRING_TRANS_SUBR(fn)     \
779         if (fn == NULL) return offset;
780
781 #define COUNT_BYTES_TRANS_SUBR(len)     \
782         offset += len;                  \
783         *bcp -= len;
784
785
786 gboolean sid_name_snooping = FALSE;
787
788 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
789    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
790    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
791 static gboolean smb_trans_reassembly = FALSE;
792 gboolean smb_dcerpc_reassembly = FALSE;
793
794 static GHashTable *smb_trans_fragment_table = NULL;
795
796 static void
797 smb_trans_reassembly_init(void)
798 {
799         fragment_table_init(&smb_trans_fragment_table);
800 }
801
802 static fragment_data *
803 smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
804                      int offset, int count, int pos, int totlen)
805 {
806         fragment_data *fd_head=NULL;
807         smb_info_t *si;
808         int more_frags;
809
810         more_frags=totlen>(pos+count);
811
812         si = (smb_info_t *)pinfo->private_data;
813         if (si->sip == NULL) {
814                 /*
815                  * We don't have the frame number of the request.
816                  *
817                  * XXX - is there truly nothing we can do here?
818                  * Can we not separately keep track of the original
819                  * transaction and its continuations, as we did
820                  * at one time?
821                  *
822                  * It is probably not much point in even trying to do something here
823                  * if we have never seen the initial request. Without the initial
824                  * request we probably miss all parameters and the begining of data
825                  * so we cant even call a subdissector since we can not determine
826                  * which type of transaction call this is.
827                  */
828                 return NULL;
829         }
830
831         if(!pinfo->fd->flags.visited){
832                 fd_head = fragment_add(tvb, offset, pinfo,
833                                        si->sip->frame_req, smb_trans_fragment_table,
834                                        pos, count, more_frags);
835         } else {
836                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
837         }
838
839         /* we only show the defragmented packet for the first fragment,
840            or else we might end up with dissecting one HUGE transaction PDU
841            a LOT of times. (first fragment is the only one containing the setup
842            bytes)
843            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction
844            SMBs. Takes a LOT of time dissecting and is not fun.
845         */
846         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
847                 return fd_head;
848         } else {
849                 return NULL;
850         }
851 }
852
853
854
855
856
857 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
858    These variables and functions are used to match
859    responses with calls
860    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
861 /*
862  * The information we need to save about a request in order to show the
863  * frame number of the request in the dissection of the reply.
864  */
865 typedef struct  {
866         guint32 frame;
867         guint32 pid_mid;
868 } smb_saved_info_key_t;
869
870 static GMemChunk *smb_saved_info_key_chunk = NULL;
871 static GMemChunk *smb_saved_info_chunk = NULL;
872 static int smb_saved_info_init_count = 200;
873
874 /* unmatched smb_saved_info structures.
875    For unmatched smb_saved_info structures we store the smb_saved_info
876    structure using the MID and the PID as the key.
877
878    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
879    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
880    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
881 */
882 static gint
883 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
884 {
885         register guint32 key1 = (guint32)k1;
886         register guint32 key2 = (guint32)k2;
887         return key1==key2;
888 }
889 static guint
890 smb_saved_info_hash_unmatched(gconstpointer k)
891 {
892         register guint32 key = (guint32)k;
893         return key;
894 }
895
896 /* matched smb_saved_info structures.
897    For matched smb_saved_info structures we store the smb_saved_info
898    structure twice in the table using the frame number, and a combination
899    of the MID and the PID, as the key.
900    The frame number is guaranteed to be unique but if ever someone makes
901    some change that will renumber the frames in a capture we are in BIG trouble.
902    This is not likely though since that would break (among other things) all the
903    reassembly routines as well.
904
905    We also need the MID as there may be more than one SMB request or reply
906    in a single frame, and we also need the PID as there may be more than
907    one outstanding request with the same MID and different PIDs.
908 */
909 static gint
910 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
911 {
912         const smb_saved_info_key_t *key1 = k1;
913         const smb_saved_info_key_t *key2 = k2;
914         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
915 }
916 static guint
917 smb_saved_info_hash_matched(gconstpointer k)
918 {
919         const smb_saved_info_key_t *key = k;
920         return key->frame + key->pid_mid;
921 }
922
923 static GMemChunk *smb_nt_transact_info_chunk = NULL;
924 static int smb_nt_transact_info_init_count = 200;
925
926 static GMemChunk *smb_transact2_info_chunk = NULL;
927 static int smb_transact2_info_init_count = 200;
928
929 /*
930  * The information we need to save about a Transaction request in order
931  * to dissect the reply; this includes information for use by the
932  * Remote API dissector.
933  */
934 static GMemChunk *smb_transact_info_chunk = NULL;
935 static int smb_transact_info_init_count = 200;
936
937 static GMemChunk *conv_tables_chunk = NULL;
938 static GSList *conv_tables = NULL;
939 static int conv_tables_count = 10;
940
941
942 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
943    End of request/response matching functions
944    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
945
946 static const value_string buffer_format_vals[] = {
947         {1,     "Data Block"},
948         {2,     "Dialect"},
949         {3,     "Pathname"},
950         {4,     "ASCII"},
951         {5,     "Variable Block"},
952         {0,     NULL}
953 };
954
955 /*
956  * UTIME - this is *almost* like a UNIX time stamp, except that it's
957  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
958  * January 1, 1970, 00:00:00 GMT.
959  *
960  * This means we have to do some extra work to convert it.  This code is
961  * based on the Samba code:
962  *
963  *      Unix SMB/Netbios implementation.
964  *      Version 1.9.
965  *      time handling functions
966  *      Copyright (C) Andrew Tridgell 1992-1998
967  */
968
969 /*
970  * Yield the difference between *A and *B, in seconds, ignoring leap
971  * seconds.
972  */
973 #define TM_YEAR_BASE 1900
974
975 static int
976 tm_diff(struct tm *a, struct tm *b)
977 {
978         int ay = a->tm_year + (TM_YEAR_BASE - 1);
979         int by = b->tm_year + (TM_YEAR_BASE - 1);
980         int intervening_leap_days =
981             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
982         int years = ay - by;
983         int days =
984             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
985         int hours = 24*days + (a->tm_hour - b->tm_hour);
986         int minutes = 60*hours + (a->tm_min - b->tm_min);
987         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
988
989         return seconds;
990 }
991
992 /*
993  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
994  * determined.
995  */
996 static int
997 TimeZone(time_t t)
998 {
999         struct tm *tm = gmtime(&t);
1000         struct tm tm_utc;
1001
1002         if (tm == NULL)
1003                 return 0;
1004         tm_utc = *tm;
1005         tm = localtime(&t);
1006         if (tm == NULL)
1007                 return 0;
1008         return tm_diff(&tm_utc,tm);
1009 }
1010
1011 /*
1012  * Return the same value as TimeZone, but it should be more efficient.
1013  *
1014  * We keep a table of DST offsets to prevent calling localtime() on each
1015  * call of this function. This saves a LOT of time on many unixes.
1016  *
1017  * Updated by Paul Eggert <eggert@twinsun.com>
1018  */
1019 #ifndef CHAR_BIT
1020 #define CHAR_BIT 8
1021 #endif
1022
1023 #ifndef TIME_T_MIN
1024 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1025                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
1026 #endif
1027 #ifndef TIME_T_MAX
1028 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
1029 #endif
1030
1031 static int
1032 TimeZoneFaster(time_t t)
1033 {
1034         static struct dst_table {time_t start,end; int zone;} *tdt;
1035         static struct dst_table *dst_table = NULL;
1036         static int table_size = 0;
1037         int i;
1038         int zone = 0;
1039
1040         if (t == 0)
1041                 t = time(NULL);
1042
1043         /* Tunis has a 8 day DST region, we need to be careful ... */
1044 #define MAX_DST_WIDTH (365*24*60*60)
1045 #define MAX_DST_SKIP (7*24*60*60)
1046
1047         for (i = 0; i < table_size; i++) {
1048                 if (t >= dst_table[i].start && t <= dst_table[i].end)
1049                         break;
1050         }
1051
1052         if (i < table_size) {
1053                 zone = dst_table[i].zone;
1054         } else {
1055                 time_t low,high;
1056
1057                 zone = TimeZone(t);
1058                 if (dst_table == NULL)
1059                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1060                 else
1061                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1062                 if (tdt == NULL) {
1063                         if (dst_table)
1064                                 free(dst_table);
1065                         table_size = 0;
1066                 } else {
1067                         dst_table = tdt;
1068                         table_size++;
1069
1070                         dst_table[i].zone = zone;
1071                         dst_table[i].start = dst_table[i].end = t;
1072
1073                         /* no entry will cover more than 6 months */
1074                         low = t - MAX_DST_WIDTH/2;
1075                         if (t < low)
1076                                 low = TIME_T_MIN;
1077
1078                         high = t + MAX_DST_WIDTH/2;
1079                         if (high < t)
1080                                 high = TIME_T_MAX;
1081
1082                         /*
1083                          * Widen the new entry using two bisection searches.
1084                          */
1085                         while (low+60*60 < dst_table[i].start) {
1086                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1087                                         t = dst_table[i].start - MAX_DST_SKIP;
1088                                 else
1089                                         t = low + (dst_table[i].start-low)/2;
1090                                 if (TimeZone(t) == zone)
1091                                         dst_table[i].start = t;
1092                                 else
1093                                         low = t;
1094                         }
1095
1096                         while (high-60*60 > dst_table[i].end) {
1097                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1098                                         t = dst_table[i].end + MAX_DST_SKIP;
1099                                 else
1100                                         t = high - (high-dst_table[i].end)/2;
1101                                 if (TimeZone(t) == zone)
1102                                         dst_table[i].end = t;
1103                                 else
1104                                         high = t;
1105                         }
1106                 }
1107         }
1108         return zone;
1109 }
1110
1111 /*
1112  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1113  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1114  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1115  * daylight savings transitions because some local times are ambiguous.
1116  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1117  */
1118 static int
1119 LocTimeDiff(time_t lt)
1120 {
1121         int d = TimeZoneFaster(lt);
1122         time_t t = lt + d;
1123
1124         /* if overflow occurred, ignore all the adjustments so far */
1125         if (((t < lt) ^ (d < 0)))
1126                 t = lt;
1127
1128         /*
1129          * Now t should be close enough to the true UTC to yield the
1130          * right answer.
1131          */
1132         return TimeZoneFaster(t);
1133 }
1134
1135 static int
1136 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1137 {
1138         guint32 timeval;
1139         nstime_t ts;
1140
1141         timeval = tvb_get_letohl(tvb, offset);
1142         if (timeval == 0xffffffff) {
1143                 proto_tree_add_text(tree, tvb, offset, 4,
1144                     "%s: No time specified (0xffffffff)",
1145                     proto_registrar_get_name(hf_date));
1146                 offset += 4;
1147                 return offset;
1148         }
1149
1150         /*
1151          * We add the local time offset.
1152          */
1153         ts.secs = timeval + LocTimeDiff(timeval);
1154         ts.nsecs = 0;
1155
1156         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1157         offset += 4;
1158
1159         return offset;
1160 }
1161
1162 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
1163
1164 /*
1165  * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits,
1166  * to an "nstime_t".
1167  * A FILETIME is a 64-bit integer, giving the time since Jan 1, 1601,
1168  * midnight "UTC", in 100ns units.
1169  * Return TRUE if the conversion succeeds, FALSE otherwise.
1170  *
1171  * According to the Samba code, it appears to be kludge-GMT (at least for
1172  * file listings). This means it's the GMT you get by taking a local time
1173  * and adding the server time zone offset.  This is NOT the same as GMT in
1174  * some cases.   However, we don't know the server time zone, so we don't
1175  * do that adjustment.
1176  *
1177  * This code is based on the Samba code:
1178  *
1179  *      Unix SMB/Netbios implementation.
1180  *      Version 1.9.
1181  *      time handling functions
1182  *      Copyright (C) Andrew Tridgell 1992-1998
1183  */
1184 static gboolean
1185 nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
1186 {
1187         double d;
1188         /* The next two lines are a fix needed for the
1189             broken SCO compiler. JRA. */
1190         time_t l_time_min = TIME_T_MIN;
1191         time_t l_time_max = TIME_T_MAX;
1192
1193         if (filetime_high == 0)
1194                 return FALSE;
1195
1196         /*
1197          * Get the time as a double, in seconds and fractional seconds.
1198          */
1199         d = ((double)filetime_high)*4.0*(double)(1<<30);
1200         d += filetime_low;
1201         d *= 1.0e-7;
1202
1203         /* Now adjust by 369 years, to make the seconds since 1970. */
1204         d -= TIME_FIXUP_CONSTANT;
1205
1206         if (!(l_time_min <= d && d <= l_time_max))
1207                 return FALSE;
1208
1209         /*
1210          * Get the time as seconds and nanoseconds.
1211          */
1212         tv->secs = d;
1213         tv->nsecs = (d - tv->secs)*1000000000;
1214
1215         return TRUE;
1216 }
1217
1218 int
1219 dissect_smb_64bit_time(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1220 {
1221         guint32 filetime_high, filetime_low;
1222         nstime_t ts;
1223
1224         /* XXX there seems also to be another special time value which is fairly common :
1225            0x40000000 00000000
1226            the meaning of this one is yet unknown
1227         */
1228         if (tree) {
1229                 filetime_low = tvb_get_letohl(tvb, offset);
1230                 filetime_high = tvb_get_letohl(tvb, offset + 4);
1231                 if (filetime_low == 0 && filetime_high == 0) {
1232                         proto_tree_add_text(tree, tvb, offset, 8,
1233                             "%s: No time specified (0)",
1234                             proto_registrar_get_name(hf_date));
1235                 } else if(filetime_low==0 && filetime_high==0x80000000){
1236                         proto_tree_add_text(tree, tvb, offset, 8,
1237                             "%s: Infinity (relative time)",
1238                             proto_registrar_get_name(hf_date));
1239                 } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
1240                         proto_tree_add_text(tree, tvb, offset, 8,
1241                             "%s: Infinity (absolute time)",
1242                             proto_registrar_get_name(hf_date));
1243                 } else {
1244                         if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
1245                                 proto_tree_add_time(tree, hf_date, tvb,
1246                                     offset, 8, &ts);
1247                         } else {
1248                                 proto_tree_add_text(tree, tvb, offset, 8,
1249                                     "%s: Time can't be converted",
1250                                     proto_registrar_get_name(hf_date));
1251                         }
1252                 }
1253         }
1254
1255         offset += 8;
1256         return offset;
1257 }
1258
1259 static int
1260 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1261     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1262 {
1263         guint16 dos_time, dos_date;
1264         proto_item *item = NULL;
1265         proto_tree *tree = NULL;
1266         struct tm tm;
1267         time_t t;
1268         static const int mday_noleap[12] = {
1269                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1270         };
1271         static const int mday_leap[12] = {
1272                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1273         };
1274 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1275         nstime_t tv;
1276
1277         if (time_first) {
1278                 dos_time = tvb_get_letohs(tvb, offset);
1279                 dos_date = tvb_get_letohs(tvb, offset+2);
1280         } else {
1281                 dos_date = tvb_get_letohs(tvb, offset);
1282                 dos_time = tvb_get_letohs(tvb, offset+2);
1283         }
1284
1285         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1286             (dos_date == 0 && dos_time == 0)) {
1287                 /*
1288                  * No date/time specified.
1289                  */
1290                 if(parent_tree){
1291                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1292                             "%s: No time specified (0x%08x)",
1293                             proto_registrar_get_name(hf_date),
1294                             (dos_date << 16) | dos_time);
1295                 }
1296                 offset += 4;
1297                 return offset;
1298         }
1299
1300         tm.tm_sec = (dos_time&0x1f)*2;
1301         tm.tm_min = (dos_time>>5)&0x3f;
1302         tm.tm_hour = (dos_time>>11)&0x1f;
1303         tm.tm_mday = dos_date&0x1f;
1304         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1305         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1306         tm.tm_isdst = -1;
1307
1308         /*
1309          * Do some sanity checks before calling "mktime()";
1310          * "mktime()" doesn't do them, it "normalizes" out-of-range
1311          * values.
1312          */
1313         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1314            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1315            (ISLEAP(tm.tm_year + 1900) ?
1316              tm.tm_mday > mday_leap[tm.tm_mon] :
1317              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1318              (t = mktime(&tm)) == -1) {
1319                 /*
1320                  * Invalid date/time.
1321                  */
1322                 if (parent_tree) {
1323                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1324                             "%s: Invalid time",
1325                             proto_registrar_get_name(hf_date));
1326                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1327                         if (time_first) {
1328                                 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);
1329                                 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);
1330                         } else {
1331                                 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);
1332                                 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);
1333                         }
1334                 }
1335                 offset += 4;
1336                 return offset;
1337         }
1338
1339         tv.secs = t;
1340         tv.nsecs = 0;
1341
1342         if(parent_tree){
1343                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1344                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1345                 if (time_first) {
1346                         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);
1347                         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);
1348                 } else {
1349                         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);
1350                         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);
1351                 }
1352         }
1353
1354         offset += 4;
1355
1356         return offset;
1357 }
1358
1359
1360 static const value_string da_access_vals[] = {
1361         { 0,            "Open for reading"},
1362         { 1,            "Open for writing"},
1363         { 2,            "Open for reading and writing"},
1364         { 3,            "Open for execute"},
1365         {0, NULL}
1366 };
1367 static const value_string da_sharing_vals[] = {
1368         { 0,            "Compatibility mode"},
1369         { 1,            "Deny read/write/execute (exclusive)"},
1370         { 2,            "Deny write"},
1371         { 3,            "Deny read/execute"},
1372         { 4,            "Deny none"},
1373         {0, NULL}
1374 };
1375 static const value_string da_locality_vals[] = {
1376         { 0,            "Locality of reference unknown"},
1377         { 1,            "Mainly sequential access"},
1378         { 2,            "Mainly random access"},
1379         { 3,            "Random access with some locality"},
1380         {0, NULL}
1381 };
1382 static const true_false_string tfs_da_caching = {
1383         "Do not cache this file",
1384         "Caching permitted on this file"
1385 };
1386 static const true_false_string tfs_da_writetru = {
1387         "Write through enabled",
1388         "Write through disabled"
1389 };
1390 static int
1391 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, char *type)
1392 {
1393         guint16 mask;
1394         proto_item *item = NULL;
1395         proto_tree *tree = NULL;
1396
1397         mask = tvb_get_letohs(tvb, offset);
1398
1399         if(parent_tree){
1400                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1401                         "%s Access: 0x%04x", type, mask);
1402                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1403         }
1404
1405         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1406                 tvb, offset, 2, mask);
1407         proto_tree_add_boolean(tree, hf_smb_access_caching,
1408                 tvb, offset, 2, mask);
1409         proto_tree_add_uint(tree, hf_smb_access_locality,
1410                 tvb, offset, 2, mask);
1411         proto_tree_add_uint(tree, hf_smb_access_sharing,
1412                 tvb, offset, 2, mask);
1413         proto_tree_add_uint(tree, hf_smb_access_mode,
1414                 tvb, offset, 2, mask);
1415
1416         offset += 2;
1417
1418         return offset;
1419 }
1420
1421 #define SMB_FILE_ATTRIBUTE_READ_ONLY            0x00000001
1422 #define SMB_FILE_ATTRIBUTE_HIDDEN                       0x00000002
1423 #define SMB_FILE_ATTRIBUTE_SYSTEM                       0x00000004
1424 #define SMB_FILE_ATTRIBUTE_VOLUME                       0x00000008
1425 #define SMB_FILE_ATTRIBUTE_DIRECTORY            0x00000010
1426 #define SMB_FILE_ATTRIBUTE_ARCHIVE                      0x00000020
1427 #define SMB_FILE_ATTRIBUTE_DEVICE                       0x00000040
1428 #define SMB_FILE_ATTRIBUTE_NORMAL                       0x00000080
1429 #define SMB_FILE_ATTRIBUTE_TEMPORARY            0x00000100
1430 #define SMB_FILE_ATTRIBUTE_SPARSE                       0x00000200
1431 #define SMB_FILE_ATTRIBUTE_REPARSE                      0x00000400
1432 #define SMB_FILE_ATTRIBUTE_COMPRESSED           0x00000800
1433 #define SMB_FILE_ATTRIBUTE_OFFLINE                      0x00001000
1434 #define SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
1435 #define SMB_FILE_ATTRIBUTE_ENCRYPTED            0x00004000
1436
1437 static const true_false_string tfs_file_attribute_read_only = {
1438         "This file is READ ONLY",
1439         "This file is NOT read only",
1440 };
1441 static const true_false_string tfs_file_attribute_hidden = {
1442         "This is a HIDDEN file",
1443         "This is NOT a hidden file"
1444 };
1445 static const true_false_string tfs_file_attribute_system = {
1446         "This is a SYSTEM file",
1447         "This is NOT a system file"
1448 };
1449 static const true_false_string tfs_file_attribute_volume = {
1450         "This is a VOLUME ID",
1451         "This is NOT a volume ID"
1452 };
1453 static const true_false_string tfs_file_attribute_directory = {
1454         "This is a DIRECTORY",
1455         "This is NOT a directory"
1456 };
1457 static const true_false_string tfs_file_attribute_archive = {
1458         "This file has been modified since last ARCHIVE",
1459         "This file has NOT been modified since last archive"
1460 };
1461 static const true_false_string tfs_file_attribute_device = {
1462         "This is a DEVICE",
1463         "This is NOT a device"
1464 };
1465 static const true_false_string tfs_file_attribute_normal = {
1466         "This file is an ordinary file",
1467         "This file has some attribute set"
1468 };
1469 static const true_false_string tfs_file_attribute_temporary = {
1470         "This is a TEMPORARY file",
1471         "This is NOT a temporary file"
1472 };
1473 static const true_false_string tfs_file_attribute_sparse = {
1474         "This is a SPARSE file",
1475         "This is NOT a sparse file"
1476 };
1477 static const true_false_string tfs_file_attribute_reparse = {
1478         "This file has an associated REPARSE POINT",
1479         "This file does NOT have an associated reparse point"
1480 };
1481 static const true_false_string tfs_file_attribute_compressed = {
1482         "This is a COMPRESSED file",
1483         "This is NOT a compressed file"
1484 };
1485 static const true_false_string tfs_file_attribute_offline = {
1486         "This file is OFFLINE",
1487         "This file is NOT offline"
1488 };
1489 static const true_false_string tfs_file_attribute_not_content_indexed = {
1490         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1491         "This file MAY be indexed by the content indexing service"
1492 };
1493 static const true_false_string tfs_file_attribute_encrypted = {
1494         "This is an ENCRYPTED file",
1495         "This is NOT an encrypted file"
1496 };
1497
1498 /*
1499  * In some places in the CIFS_TR_1p00.pdf, from SNIA, file attributes are 
1500  * listed as USHORT, and seem to be in packets in the wild, while in other
1501  * places they are listed as ULONG, and also seem to be.
1502  *
1503  * So, I (Richard Sharpe), added a parameter to allow us to specify how many
1504  * bytes to consume.
1505  */
1506
1507 static int
1508 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1509                         int bytes)
1510 {
1511         guint16 mask;
1512         proto_item *item = NULL;
1513         proto_tree *tree = NULL;
1514
1515         if (bytes != 2 && bytes != 4) {
1516
1517                 fprintf(stderr, "Incorrect number of bytes passed to dissect_file_attributes.\nMust be 2 or 4, was %d\n", bytes);
1518                 exit(1);
1519
1520         }
1521
1522         /*
1523          * The actual bits of interest appear to only be a USHORT
1524          */
1525         /* FIXME if this ever changes! */
1526         mask = tvb_get_letohs(tvb, offset);
1527
1528         if(parent_tree){
1529                 item = proto_tree_add_text(parent_tree, tvb, offset, bytes,
1530                         "File Attributes: 0x%08x", mask);
1531                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1532         }
1533         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted, 
1534                                tvb, offset, bytes, mask);       
1535         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed, 
1536                                tvb, offset, bytes, mask);
1537         proto_tree_add_boolean(tree, hf_smb_file_attr_offline, 
1538                                tvb, offset, bytes, mask);
1539         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed, 
1540                                tvb, offset, bytes, mask);
1541         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse, 
1542                                tvb, offset, bytes, mask);
1543         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse, 
1544                                tvb, offset, bytes, mask);
1545         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary, 
1546                                tvb, offset, bytes, mask);
1547         proto_tree_add_boolean(tree, hf_smb_file_attr_normal, 
1548                                tvb, offset, bytes, mask);
1549         proto_tree_add_boolean(tree, hf_smb_file_attr_device, 
1550                                tvb, offset, bytes, mask);
1551         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1552                 tvb, offset, bytes, mask);
1553         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1554                 tvb, offset, bytes, mask);
1555         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1556                 tvb, offset, bytes, mask);
1557         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1558                 tvb, offset, bytes, mask);
1559         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1560                 tvb, offset, bytes, mask);
1561         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1562                 tvb, offset, bytes, mask);
1563
1564         offset += bytes;
1565
1566         return offset;
1567 }
1568
1569 /* 3.11 */
1570 static int
1571 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1572 {
1573         guint32 mask;
1574         proto_item *item = NULL;
1575         proto_tree *tree = NULL;
1576
1577         mask = tvb_get_letohl(tvb, offset);
1578
1579         if(parent_tree){
1580                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1581                         "File Attributes: 0x%08x", mask);
1582                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1583         }
1584
1585         /*
1586          * XXX - Network Monitor disagrees on some of the
1587          * bits, e.g. the bits above temporary are "atomic write"
1588          * and "transaction write", and it says nothing about the
1589          * bits above that.
1590          *
1591          * Does the Win32 API documentation, or the NT Native API book,
1592          * suggest anything?
1593          */
1594         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1595                 tvb, offset, 4, mask);
1596         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1597                 tvb, offset, 4, mask);
1598         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1599                 tvb, offset, 4, mask);
1600         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1601                 tvb, offset, 4, mask);
1602         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1603                 tvb, offset, 4, mask);
1604         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1605                 tvb, offset, 4, mask);
1606         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1607                 tvb, offset, 4, mask);
1608         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1609                 tvb, offset, 4, mask);
1610         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1611                 tvb, offset, 4, mask);
1612         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1613                 tvb, offset, 4, mask);
1614         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1615                 tvb, offset, 4, mask);
1616         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1617                 tvb, offset, 4, mask);
1618         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1619                 tvb, offset, 4, mask);
1620         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1621                 tvb, offset, 4, mask);
1622         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1623                 tvb, offset, 4, mask);
1624
1625         offset += 4;
1626
1627         return offset;
1628 }
1629
1630 static int
1631 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1632 {
1633         guint8 mask;
1634         proto_item *item = NULL;
1635         proto_tree *tree = NULL;
1636
1637         mask = tvb_get_guint8(tvb, offset);
1638
1639         if(parent_tree){
1640                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1641                         "File Attributes: 0x%02x", mask);
1642                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1643         }
1644         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1645                 tvb, offset, 1, mask);
1646         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1647                 tvb, offset, 1, mask);
1648         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1649                 tvb, offset, 1, mask);
1650         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1651                 tvb, offset, 1, mask);
1652         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1653                 tvb, offset, 1, mask);
1654         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1655                 tvb, offset, 1, mask);
1656
1657         offset += 1;
1658
1659         return offset;
1660 }
1661
1662 static const true_false_string tfs_search_attribute_read_only = {
1663         "Include READ ONLY files in search results",
1664         "Do NOT include read only files in search results",
1665 };
1666 static const true_false_string tfs_search_attribute_hidden = {
1667         "Include HIDDEN files in search results",
1668         "Do NOT include hidden files in search results"
1669 };
1670 static const true_false_string tfs_search_attribute_system = {
1671         "Include SYSTEM files in search results",
1672         "Do NOT include system files in search results"
1673 };
1674 static const true_false_string tfs_search_attribute_volume = {
1675         "Include VOLUME IDs in search results",
1676         "Do NOT include volume IDs in search results"
1677 };
1678 static const true_false_string tfs_search_attribute_directory = {
1679         "Include DIRECTORIES in search results",
1680         "Do NOT include directories in search results"
1681 };
1682 static const true_false_string tfs_search_attribute_archive = {
1683         "Include ARCHIVE files in search results",
1684         "Do NOT include archive files in search results"
1685 };
1686
1687 static int
1688 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1689 {
1690         guint16 mask;
1691         proto_item *item = NULL;
1692         proto_tree *tree = NULL;
1693
1694         mask = tvb_get_letohs(tvb, offset);
1695
1696         if(parent_tree){
1697                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1698                         "Search Attributes: 0x%04x", mask);
1699                 tree = proto_item_add_subtree(item, ett_smb_search);
1700         }
1701
1702         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1703                 tvb, offset, 2, mask);
1704         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1705                 tvb, offset, 2, mask);
1706         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1707                 tvb, offset, 2, mask);
1708         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1709                 tvb, offset, 2, mask);
1710         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1711                 tvb, offset, 2, mask);
1712         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1713                 tvb, offset, 2, mask);
1714
1715         offset += 2;
1716         return offset;
1717 }
1718
1719 #if 0
1720 /*
1721  * XXX - this isn't used.
1722  * Is this used for anything?  NT Create AndX doesn't use it.
1723  * Is there some 16-bit attribute field with more bits than Read Only,
1724  * Hidden, System, Volume ID, Directory, and Archive?
1725  */
1726 static int
1727 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1728 {
1729         guint32 mask;
1730         proto_item *item = NULL;
1731         proto_tree *tree = NULL;
1732
1733         mask = tvb_get_letohl(tvb, offset);
1734
1735         if(parent_tree){
1736                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1737                         "File Attributes: 0x%08x", mask);
1738                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1739         }
1740         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1741                 tvb, offset, 2, mask);
1742         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1743                 tvb, offset, 2, mask);
1744         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1745                 tvb, offset, 2, mask);
1746         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1747                 tvb, offset, 2, mask);
1748         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1749                 tvb, offset, 2, mask);
1750         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1751                 tvb, offset, 2, mask);
1752         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1753                 tvb, offset, 2, mask);
1754         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1755                 tvb, offset, 2, mask);
1756         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1757                 tvb, offset, 2, mask);
1758         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1759                 tvb, offset, 2, mask);
1760         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1761                 tvb, offset, 2, mask);
1762         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1763                 tvb, offset, 2, mask);
1764         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1765                 tvb, offset, 2, mask);
1766         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1767                 tvb, offset, 2, mask);
1768         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1769                 tvb, offset, 2, mask);
1770
1771         offset += 2;
1772
1773         return offset;
1774 }
1775 #endif
1776
1777
1778 #define SERVER_CAP_RAW_MODE            0x00000001
1779 #define SERVER_CAP_MPX_MODE            0x00000002
1780 #define SERVER_CAP_UNICODE             0x00000004
1781 #define SERVER_CAP_LARGE_FILES         0x00000008
1782 #define SERVER_CAP_NT_SMBS             0x00000010
1783 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1784 #define SERVER_CAP_STATUS32            0x00000040
1785 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1786 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1787 #define SERVER_CAP_NT_FIND             0x00000200
1788 #define SERVER_CAP_DFS                 0x00001000
1789 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1790 #define SERVER_CAP_LARGE_READX         0x00004000
1791 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1792 #define SERVER_CAP_UNIX                0x00800000
1793 #define SERVER_CAP_RESERVED            0x02000000
1794 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1795 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1796 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1797 static const true_false_string tfs_server_cap_raw_mode = {
1798         "Read Raw and Write Raw are supported",
1799         "Read Raw and Write Raw are not supported"
1800 };
1801 static const true_false_string tfs_server_cap_mpx_mode = {
1802         "Read Mpx and Write Mpx are supported",
1803         "Read Mpx and Write Mpx are not supported"
1804 };
1805 static const true_false_string tfs_server_cap_unicode = {
1806         "Unicode strings are supported",
1807         "Unicode strings are not supported"
1808 };
1809 static const true_false_string tfs_server_cap_large_files = {
1810         "Large files are supported",
1811         "Large files are not supported",
1812 };
1813 static const true_false_string tfs_server_cap_nt_smbs = {
1814         "NT SMBs are supported",
1815         "NT SMBs are not supported"
1816 };
1817 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1818         "RPC remote APIs are supported",
1819         "RPC remote APIs are not supported"
1820 };
1821 static const true_false_string tfs_server_cap_nt_status = {
1822         "NT status codes are supported",
1823         "NT status codes are not supported"
1824 };
1825 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1826         "Level 2 oplocks are supported",
1827         "Level 2 oplocks are not supported"
1828 };
1829 static const true_false_string tfs_server_cap_lock_and_read = {
1830         "Lock and Read is supported",
1831         "Lock and Read is not supported"
1832 };
1833 static const true_false_string tfs_server_cap_nt_find = {
1834         "NT Find is supported",
1835         "NT Find is not supported"
1836 };
1837 static const true_false_string tfs_server_cap_dfs = {
1838         "Dfs is supported",
1839         "Dfs is not supported"
1840 };
1841 static const true_false_string tfs_server_cap_infolevel_passthru = {
1842         "NT information level request passthrough is supported",
1843         "NT information level request passthrough is not supported"
1844 };
1845 static const true_false_string tfs_server_cap_large_readx = {
1846         "Large Read andX is supported",
1847         "Large Read andX is not supported"
1848 };
1849 static const true_false_string tfs_server_cap_large_writex = {
1850         "Large Write andX is supported",
1851         "Large Write andX is not supported"
1852 };
1853 static const true_false_string tfs_server_cap_unix = {
1854         "UNIX extensions are supported",
1855         "UNIX extensions are not supported"
1856 };
1857 static const true_false_string tfs_server_cap_reserved = {
1858         "Reserved",
1859         "Reserved"
1860 };
1861 static const true_false_string tfs_server_cap_bulk_transfer = {
1862         "Bulk Read and Bulk Write are supported",
1863         "Bulk Read and Bulk Write are not supported"
1864 };
1865 static const true_false_string tfs_server_cap_compressed_data = {
1866         "Compressed data transfer is supported",
1867         "Compressed data transfer is not supported"
1868 };
1869 static const true_false_string tfs_server_cap_extended_security = {
1870         "Extended security exchanges are supported",
1871         "Extended security exchanges are not supported"
1872 };
1873 static int
1874 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1875 {
1876         guint32 mask;
1877         proto_item *item = NULL;
1878         proto_tree *tree = NULL;
1879
1880         mask = tvb_get_letohl(tvb, offset);
1881
1882         if(parent_tree){
1883                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1884                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1885         }
1886
1887         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1888                 tvb, offset, 4, mask);
1889         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1890                 tvb, offset, 4, mask);
1891         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1892                 tvb, offset, 4, mask);
1893         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1894                 tvb, offset, 4, mask);
1895         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1896                 tvb, offset, 4, mask);
1897         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1898                 tvb, offset, 4, mask);
1899         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1900                 tvb, offset, 4, mask);
1901         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1902                 tvb, offset, 4, mask);
1903         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1904                 tvb, offset, 4, mask);
1905         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1906                 tvb, offset, 4, mask);
1907         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1908                 tvb, offset, 4, mask);
1909         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1910                 tvb, offset, 4, mask);
1911         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1912                 tvb, offset, 4, mask);
1913         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1914                 tvb, offset, 4, mask);
1915         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1916                 tvb, offset, 4, mask);
1917         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1918                 tvb, offset, 4, mask);
1919         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1920                 tvb, offset, 4, mask);
1921         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1922                 tvb, offset, 4, mask);
1923         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1924                 tvb, offset, 4, mask);
1925
1926         return mask;
1927 }
1928
1929 #define RAWMODE_READ   0x01
1930 #define RAWMODE_WRITE  0x02
1931 static const true_false_string tfs_rm_read = {
1932         "Read Raw is supported",
1933         "Read Raw is not supported"
1934 };
1935 static const true_false_string tfs_rm_write = {
1936         "Write Raw is supported",
1937         "Write Raw is not supported"
1938 };
1939
1940 static int
1941 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1942 {
1943         guint16 mask;
1944         proto_item *item = NULL;
1945         proto_tree *tree = NULL;
1946
1947         mask = tvb_get_letohs(tvb, offset);
1948
1949         if(parent_tree){
1950                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1951                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1952         }
1953
1954         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
1955         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
1956
1957         offset += 2;
1958
1959         return offset;
1960 }
1961
1962 #define SECURITY_MODE_MODE             0x01
1963 #define SECURITY_MODE_PASSWORD         0x02
1964 #define SECURITY_MODE_SIGNATURES       0x04
1965 #define SECURITY_MODE_SIG_REQUIRED     0x08
1966 static const true_false_string tfs_sm_mode = {
1967         "USER security mode",
1968         "SHARE security mode"
1969 };
1970 static const true_false_string tfs_sm_password = {
1971         "ENCRYPTED password. Use challenge/response",
1972         "PLAINTEXT password"
1973 };
1974 static const true_false_string tfs_sm_signatures = {
1975         "Security signatures ENABLED",
1976         "Security signatures NOT enabled"
1977 };
1978 static const true_false_string tfs_sm_sig_required = {
1979         "Security signatures REQUIRED",
1980         "Security signatures NOT required"
1981 };
1982
1983 static int
1984 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
1985 {
1986         guint16 mask = 0;
1987         proto_item *item = NULL;
1988         proto_tree *tree = NULL;
1989
1990         switch(wc){
1991         case 13:
1992                 mask = tvb_get_letohs(tvb, offset);
1993                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1994                                 "Security Mode: 0x%04x", mask);
1995                 tree = proto_item_add_subtree(item, ett_smb_mode);
1996                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
1997                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
1998                 offset += 2;
1999                 break;
2000
2001         case 17:
2002                 mask = tvb_get_guint8(tvb, offset);
2003                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
2004                                 "Security Mode: 0x%02x", mask);
2005                 tree = proto_item_add_subtree(item, ett_smb_mode);
2006                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2007                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2008                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2009                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2010                 offset += 1;
2011                 break;
2012         }
2013
2014         return offset;
2015 }
2016
2017 static int
2018 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2019 {
2020         proto_item *it = NULL;
2021         proto_tree *tr = NULL;
2022         guint16 bc;
2023         guint8 wc;
2024
2025         WORD_COUNT;
2026
2027         BYTE_COUNT;
2028
2029         if(tree){
2030                 it = proto_tree_add_text(tree, tvb, offset, bc,
2031                                 "Requested Dialects");
2032                 tr = proto_item_add_subtree(it, ett_smb_dialects);
2033         }
2034
2035         while(bc){
2036                 int len;
2037                 const guint8 *str;
2038                 proto_item *dit = NULL;
2039                 proto_tree *dtr = NULL;
2040
2041                 /* XXX - what if this runs past bc? */
2042                 len = tvb_strsize(tvb, offset+1);
2043                 str = tvb_get_ptr(tvb, offset+1, len);
2044
2045                 if(tr){
2046                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2047                                         "Dialect: %s", str);
2048                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2049                 }
2050
2051                 /* Buffer Format */
2052                 CHECK_BYTE_COUNT(1);
2053                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2054                         TRUE);
2055                 COUNT_BYTES(1);
2056
2057                 /*Dialect Name */
2058                 CHECK_BYTE_COUNT(len);
2059                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2060                         len, str);
2061                 COUNT_BYTES(len);
2062         }
2063
2064         END_OF_SMB
2065
2066         return offset;
2067 }
2068
2069 static int
2070 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2071 {
2072         smb_info_t *si = pinfo->private_data;
2073         guint8 wc;
2074         guint16 dialect;
2075         const char *dn;
2076         int dn_len;
2077         guint16 bc;
2078         guint16 ekl=0;
2079         guint32 caps=0;
2080         gint16 tz;
2081
2082         WORD_COUNT;
2083
2084         /* Dialect Index */
2085         dialect = tvb_get_letohs(tvb, offset);
2086         switch(wc){
2087         case 1:
2088                 if(dialect==0xffff){
2089                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2090                                 tvb, offset, 2, dialect,
2091                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2092                 } else {
2093                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2094                                 tvb, offset, 2, dialect);
2095                 }
2096                 break;
2097         case 13:
2098                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2099                         tvb, offset, 2, dialect,
2100                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2101                 break;
2102         case 17:
2103                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2104                         tvb, offset, 2, dialect,
2105                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2106                 break;
2107         default:
2108                 proto_tree_add_text(tree, tvb, offset, wc*2,
2109                         "Words for unknown response format");
2110                 offset += wc*2;
2111                 goto bytecount;
2112         }
2113         offset += 2;
2114
2115         switch(wc){
2116         case 13:
2117                 /* Security Mode */
2118                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2119
2120                 /* Maximum Transmit Buffer Size */
2121                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2122                         tvb, offset, 2, TRUE);
2123                 offset += 2;
2124
2125                 /* Maximum Multiplex Count */
2126                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2127                         tvb, offset, 2, TRUE);
2128                 offset += 2;
2129
2130                 /* Maximum Vcs Number */
2131                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2132                         tvb, offset, 2, TRUE);
2133                 offset += 2;
2134
2135                 /* raw mode */
2136                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2137
2138                 /* session key */
2139                 proto_tree_add_item(tree, hf_smb_session_key,
2140                         tvb, offset, 4, TRUE);
2141                 offset += 4;
2142
2143                 /* current time and date at server */
2144                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2145                     TRUE);
2146
2147                 /* time zone */
2148                 tz = tvb_get_letohs(tvb, offset);
2149                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2150                 offset += 2;
2151
2152                 /* encryption key length */
2153                 ekl = tvb_get_letohs(tvb, offset);
2154                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2155                 offset += 2;
2156
2157                 /* 2 reserved bytes */
2158                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2159                 offset += 2;
2160
2161                 break;
2162
2163         case 17:
2164                 /* Security Mode */
2165                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2166
2167                 /* Maximum Multiplex Count */
2168                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2169                         tvb, offset, 2, TRUE);
2170                 offset += 2;
2171
2172                 /* Maximum Vcs Number */
2173                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2174                         tvb, offset, 2, TRUE);
2175                 offset += 2;
2176
2177                 /* Maximum Transmit Buffer Size */
2178                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2179                         tvb, offset, 4, TRUE);
2180                 offset += 4;
2181
2182                 /* maximum raw buffer size */
2183                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2184                         tvb, offset, 4, TRUE);
2185                 offset += 4;
2186
2187                 /* session key */
2188                 proto_tree_add_item(tree, hf_smb_session_key,
2189                         tvb, offset, 4, TRUE);
2190                 offset += 4;
2191
2192                 /* server capabilities */
2193                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2194                 offset += 4;
2195
2196                 /* system time */
2197                 offset = dissect_smb_64bit_time(tvb, tree, offset,
2198                                 hf_smb_system_time);
2199
2200                 /* time zone */
2201                 tz = tvb_get_letohs(tvb, offset);
2202                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2203                         tvb, offset, 2, tz,
2204                         "Server Time Zone: %d min from UTC", tz);
2205                 offset += 2;
2206
2207                 /* encryption key length */
2208                 ekl = tvb_get_guint8(tvb, offset);
2209                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2210                         tvb, offset, 1, ekl);
2211                 offset += 1;
2212
2213                 break;
2214         }
2215
2216         BYTE_COUNT;
2217
2218         switch(wc){
2219         case 13:
2220                 /* challenge/response encryption key */
2221                 if(ekl){
2222                         CHECK_BYTE_COUNT(ekl);
2223                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2224                         COUNT_BYTES(ekl);
2225                 }
2226
2227                 /*
2228                  * Primary domain.
2229                  *
2230                  * XXX - not present if negotiated dialect isn't
2231                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2232                  * have to see the request, or assume what dialect strings
2233                  * were sent, to determine that.
2234                  *
2235                  * Is this something other than a primary domain if the
2236                  * negotiated dialect is Windows for Workgroups 3.1a?
2237                  * It appears to be 8 bytes of binary data in at least
2238                  * one capture - is that an encryption key or something
2239                  * such as that?
2240                  */
2241                 dn = get_unicode_or_ascii_string(tvb, &offset,
2242                         si->unicode, &dn_len, FALSE, FALSE, &bc);
2243                 if (dn == NULL)
2244                         goto endofcommand;
2245                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2246                         offset, dn_len,dn);
2247                 COUNT_BYTES(dn_len);
2248                 break;
2249
2250         case 17:
2251                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2252                         /* challenge/response encryption key */
2253                         /* XXX - is this aligned on an even boundary? */
2254                         if(ekl){
2255                                 CHECK_BYTE_COUNT(ekl);
2256                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2257                                         tvb, offset, ekl, TRUE);
2258                                 COUNT_BYTES(ekl);
2259                         }
2260
2261                         /* domain */
2262                         /* this string is special, unicode is flagged in caps */
2263                         /* This string is NOT padded to be 16bit aligned.
2264                            (seen in actual capture)
2265                            XXX - I've seen a capture where it appears to be
2266                            so aligned, but I've also seen captures where
2267                            it is.  The captures where it appeared to be
2268                            aligned may have been from buggy servers. */
2269                         /* However, don't get rid of existing setting */
2270                         si->unicode = (caps&SERVER_CAP_UNICODE) ||
2271                           si->unicode;
2272
2273                         dn = get_unicode_or_ascii_string(tvb,
2274                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2275                                 &bc);
2276                         if (dn == NULL)
2277                                 goto endofcommand;
2278                         proto_tree_add_string(tree, hf_smb_primary_domain,
2279                                 tvb, offset, dn_len, dn);
2280                         COUNT_BYTES(dn_len);
2281
2282                         /* server name, seen in w2k pro capture */
2283                         dn = get_unicode_or_ascii_string(tvb,
2284                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2285                                 &bc);
2286                         if (dn == NULL)
2287                                 goto endofcommand;
2288                         proto_tree_add_string(tree, hf_smb_server,
2289                                 tvb, offset, dn_len, dn);
2290                         COUNT_BYTES(dn_len);
2291
2292                 } else {
2293                         proto_item *blob_item;
2294
2295                         /* guid */
2296                         /* XXX - show it in the standard Microsoft format
2297                            for GUIDs? */
2298                         CHECK_BYTE_COUNT(16);
2299                         proto_tree_add_item(tree, hf_smb_server_guid,
2300                                 tvb, offset, 16, TRUE);
2301                         COUNT_BYTES(16);
2302
2303                         blob_item = proto_tree_add_item(
2304                                 tree, hf_smb_security_blob,
2305                                 tvb, offset, bc, TRUE);
2306
2307                         /* security blob */
2308                         /* 
2309                          * If Extended security and BCC == 16, then raw 
2310                          * NTLMSSP is in use. We need to save this info
2311                          */
2312  
2313                         if(bc){
2314                                 tvbuff_t *gssapi_tvb;
2315                                 proto_tree *gssapi_tree;
2316
2317                                 gssapi_tree = proto_item_add_subtree(
2318                                         blob_item, ett_smb_secblob);
2319
2320                                 gssapi_tvb = tvb_new_subset(
2321                                         tvb, offset, bc, bc);
2322
2323                                 call_dissector(
2324                                         gssapi_handle, gssapi_tvb, pinfo,
2325                                         gssapi_tree);
2326
2327                                 if (si->ct)
2328                                   si->ct->raw_ntlmssp = 0;
2329
2330                                 COUNT_BYTES(bc);
2331                         }
2332                         else { 
2333
2334                           /*
2335                            * There is no blob. We just have to make sure
2336                            * that subsequent routines know to call the 
2337                            * right things ...
2338                            */
2339
2340                           if (si->ct)
2341                             si->ct->raw_ntlmssp = 1;
2342
2343                         }
2344                 }
2345                 break;
2346         }
2347
2348         END_OF_SMB
2349
2350         return offset;
2351 }
2352
2353
2354 static int
2355 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2356 {
2357         smb_info_t *si = pinfo->private_data;
2358         int dn_len;
2359         const char *dn;
2360         guint8 wc;
2361         guint16 bc;
2362
2363         WORD_COUNT;
2364
2365         BYTE_COUNT;
2366
2367         /* buffer format */
2368         CHECK_BYTE_COUNT(1);
2369         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2370         COUNT_BYTES(1);
2371
2372         /* dir name */
2373         dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
2374                 FALSE, FALSE, &bc);
2375         if (dn == NULL)
2376                 goto endofcommand;
2377         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2378                 dn);
2379         COUNT_BYTES(dn_len);
2380
2381         if (check_col(pinfo->cinfo, COL_INFO)) {
2382                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s", dn);
2383         }
2384
2385         END_OF_SMB
2386
2387         return offset;
2388 }
2389
2390 static int
2391 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2392 {
2393         guint8 wc;
2394         guint16 bc;
2395
2396         WORD_COUNT;
2397
2398         BYTE_COUNT;
2399
2400         END_OF_SMB
2401
2402         return offset;
2403 }
2404
2405 static int
2406 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2407 {
2408         guint16 ec, bc;
2409         guint8 wc;
2410
2411         WORD_COUNT;
2412
2413         /* echo count */
2414         ec = tvb_get_letohs(tvb, offset);
2415         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2416         offset += 2;
2417
2418         BYTE_COUNT;
2419
2420         if (bc != 0) {
2421                 /* echo data */
2422                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2423                 COUNT_BYTES(bc);
2424         }
2425
2426         END_OF_SMB
2427
2428         return offset;
2429 }
2430
2431 static int
2432 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2433 {
2434         guint16 bc;
2435         guint8 wc;
2436
2437         WORD_COUNT;
2438
2439         /* echo sequence number */
2440         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2441         offset += 2;
2442
2443         BYTE_COUNT;
2444
2445         if (bc != 0) {
2446                 /* echo data */
2447                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2448                 COUNT_BYTES(bc);
2449         }
2450
2451         END_OF_SMB
2452
2453         return offset;
2454 }
2455
2456 static int
2457 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2458 {
2459         smb_info_t *si = pinfo->private_data;
2460         int an_len, pwlen;
2461         const char *an;
2462         guint8 wc;
2463         guint16 bc;
2464
2465         WORD_COUNT;
2466
2467         BYTE_COUNT;
2468
2469         /* buffer format */
2470         CHECK_BYTE_COUNT(1);
2471         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2472         COUNT_BYTES(1);
2473
2474         /* Path */
2475         an = get_unicode_or_ascii_string(tvb, &offset,
2476                 si->unicode, &an_len, FALSE, FALSE, &bc);
2477         if (an == NULL)
2478                 goto endofcommand;
2479         proto_tree_add_string(tree, hf_smb_path, tvb,
2480                 offset, an_len, an);
2481         COUNT_BYTES(an_len);
2482
2483         if (check_col(pinfo->cinfo, COL_INFO)) {
2484                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
2485         }
2486
2487         /* buffer format */
2488         CHECK_BYTE_COUNT(1);
2489         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2490         COUNT_BYTES(1);
2491
2492         /* password, ANSI */
2493         /* XXX - what if this runs past bc? */
2494         pwlen = tvb_strsize(tvb, offset);
2495         CHECK_BYTE_COUNT(pwlen);
2496         proto_tree_add_item(tree, hf_smb_password,
2497                 tvb, offset, pwlen, TRUE);
2498         COUNT_BYTES(pwlen);
2499
2500         /* buffer format */
2501         CHECK_BYTE_COUNT(1);
2502         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2503         COUNT_BYTES(1);
2504
2505         /* Service */
2506         an = get_unicode_or_ascii_string(tvb, &offset,
2507                 si->unicode, &an_len, FALSE, FALSE, &bc);
2508         if (an == NULL)
2509                 goto endofcommand;
2510         proto_tree_add_string(tree, hf_smb_service, tvb,
2511                 offset, an_len, an);
2512         COUNT_BYTES(an_len);
2513
2514         END_OF_SMB
2515
2516         return offset;
2517 }
2518
2519 static int
2520 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2521 {
2522         guint8 wc;
2523         guint16 bc;
2524
2525         WORD_COUNT;
2526
2527         /* Maximum Buffer Size */
2528         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2529         offset += 2;
2530
2531         /* tid */
2532         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2533         offset += 2;
2534
2535         BYTE_COUNT;
2536
2537         END_OF_SMB
2538
2539         return offset;
2540 }
2541
2542
2543 static const true_false_string tfs_of_create = {
2544         "Create file if it does not exist",
2545         "Fail if file does not exist"
2546 };
2547 static const value_string of_open[] = {
2548         { 0,            "Fail if file exists"},
2549         { 1,            "Open file if it exists"},
2550         { 2,            "Truncate file if it exists"},
2551         {0, NULL}
2552 };
2553 static int
2554 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2555 {
2556         guint16 mask;
2557         proto_item *item = NULL;
2558         proto_tree *tree = NULL;
2559
2560         mask = tvb_get_letohs(tvb, offset);
2561
2562         if(parent_tree){
2563                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2564                         "Open Function: 0x%04x", mask);
2565                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2566         }
2567
2568         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2569                 tvb, offset, 2, mask);
2570         proto_tree_add_uint(tree, hf_smb_open_function_open,
2571                 tvb, offset, 2, mask);
2572
2573         offset += 2;
2574
2575         return offset;
2576 }
2577
2578
2579 static const true_false_string tfs_mf_file = {
2580         "Target must be a file",
2581         "Target needn't be a file"
2582 };
2583 static const true_false_string tfs_mf_dir = {
2584         "Target must be a directory",
2585         "Target needn't be a directory"
2586 };
2587 static const true_false_string tfs_mf_verify = {
2588         "MUST verify all writes",
2589         "Don't have to verify writes"
2590 };
2591 static int
2592 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2593 {
2594         guint16 mask;
2595         proto_item *item = NULL;
2596         proto_tree *tree = NULL;
2597
2598         mask = tvb_get_letohs(tvb, offset);
2599
2600         if(parent_tree){
2601                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2602                         "Flags: 0x%04x", mask);
2603                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2604         }
2605
2606         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2607                 tvb, offset, 2, mask);
2608         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2609                 tvb, offset, 2, mask);
2610         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2611                 tvb, offset, 2, mask);
2612
2613         offset += 2;
2614
2615         return offset;
2616 }
2617
2618 static const true_false_string tfs_cf_mode = {
2619         "ASCII",
2620         "Binary"
2621 };
2622 static const true_false_string tfs_cf_tree_copy = {
2623         "Copy is a tree copy",
2624         "Copy is a file copy"
2625 };
2626 static const true_false_string tfs_cf_ea_action = {
2627         "Fail copy",
2628         "Discard EAs"
2629 };
2630 static int
2631 dissect_copy_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_copy_flags_ea_action,
2646                 tvb, offset, 2, mask);
2647         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2648                 tvb, offset, 2, mask);
2649         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2650                 tvb, offset, 2, mask);
2651         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2652                 tvb, offset, 2, mask);
2653         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2654                 tvb, offset, 2, mask);
2655         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2656                 tvb, offset, 2, mask);
2657         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2658                 tvb, offset, 2, mask);
2659
2660         offset += 2;
2661
2662         return offset;
2663 }
2664
2665 static int
2666 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2667 {
2668         smb_info_t *si = pinfo->private_data;
2669         int fn_len;
2670         guint16 tid;
2671         guint16 bc;
2672         guint8 wc;
2673         const char *fn;
2674
2675         WORD_COUNT;
2676
2677         /* tid */
2678         tid = tvb_get_letohs(tvb, offset);
2679         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2680                 "TID (target): 0x%04x", tid);
2681         offset += 2;
2682
2683         /* open function */
2684         offset = dissect_open_function(tvb, tree, offset);
2685
2686         /* move flags */
2687         offset = dissect_move_flags(tvb, tree, offset);
2688
2689         BYTE_COUNT;
2690
2691         /* buffer format */
2692         CHECK_BYTE_COUNT(1);
2693         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2694         COUNT_BYTES(1);
2695
2696         /* file name */
2697         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2698                 FALSE, FALSE, &bc);
2699         if (fn == NULL)
2700                 goto endofcommand;
2701         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2702                 fn_len, fn, "Old File Name: %s", fn);
2703         COUNT_BYTES(fn_len);
2704
2705         if (check_col(pinfo->cinfo, COL_INFO)) {
2706                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2707         }
2708
2709         /* buffer format */
2710         CHECK_BYTE_COUNT(1);
2711         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2712         COUNT_BYTES(1);
2713
2714         /* file name */
2715         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2716                 FALSE, FALSE, &bc);
2717         if (fn == NULL)
2718                 goto endofcommand;
2719         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2720                 fn_len, fn, "New File Name: %s", fn);
2721         COUNT_BYTES(fn_len);
2722
2723         if (check_col(pinfo->cinfo, COL_INFO)) {
2724                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2725         }
2726
2727         END_OF_SMB
2728
2729         return offset;
2730 }
2731
2732 static int
2733 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2734 {
2735         smb_info_t *si = pinfo->private_data;
2736         int fn_len;
2737         guint16 tid;
2738         guint16 bc;
2739         guint8 wc;
2740         const char *fn;
2741
2742         WORD_COUNT;
2743
2744         /* tid */
2745         tid = tvb_get_letohs(tvb, offset);
2746         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2747                 "TID (target): 0x%04x", tid);
2748         offset += 2;
2749
2750         /* open function */
2751         offset = dissect_open_function(tvb, tree, offset);
2752
2753         /* copy flags */
2754         offset = dissect_copy_flags(tvb, tree, offset);
2755
2756         BYTE_COUNT;
2757
2758         /* buffer format */
2759         CHECK_BYTE_COUNT(1);
2760         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2761         COUNT_BYTES(1);
2762
2763         /* file name */
2764         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2765                 FALSE, FALSE, &bc);
2766         if (fn == NULL)
2767                 goto endofcommand;
2768         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2769                 fn_len, fn, "Source File Name: %s", fn);
2770         COUNT_BYTES(fn_len);
2771
2772         if (check_col(pinfo->cinfo, COL_INFO)) {
2773                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s", fn);
2774         }
2775
2776         /* buffer format */
2777         CHECK_BYTE_COUNT(1);
2778         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2779         COUNT_BYTES(1);
2780
2781         /* file name */
2782         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2783                 FALSE, FALSE, &bc);
2784         if (fn == NULL)
2785                 goto endofcommand;
2786         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2787                 fn_len, fn, "Destination File Name: %s", fn);
2788         COUNT_BYTES(fn_len);
2789
2790         if (check_col(pinfo->cinfo, COL_INFO)) {
2791                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", fn);
2792         }
2793
2794         END_OF_SMB
2795
2796         return offset;
2797 }
2798
2799 static int
2800 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2801 {
2802         smb_info_t *si = pinfo->private_data;
2803         int fn_len;
2804         const char *fn;
2805         guint8 wc;
2806         guint16 bc;
2807
2808         WORD_COUNT;
2809
2810         /* # of files moved */
2811         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
2812         offset += 2;
2813
2814         BYTE_COUNT;
2815
2816         /* buffer format */
2817         CHECK_BYTE_COUNT(1);
2818         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2819         COUNT_BYTES(1);
2820
2821         /* file name */
2822         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2823                 FALSE, FALSE, &bc);
2824         if (fn == NULL)
2825                 goto endofcommand;
2826         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2827                 fn);
2828         COUNT_BYTES(fn_len);
2829
2830         END_OF_SMB
2831
2832         return offset;
2833 }
2834
2835 static int
2836 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2837 {
2838         smb_info_t *si = pinfo->private_data;
2839         int fn_len;
2840         const char *fn;
2841         guint8 wc;
2842         guint16 bc;
2843
2844         WORD_COUNT;
2845
2846         /* desired access */
2847         offset = dissect_access(tvb, tree, offset, "Desired");
2848
2849         /* Search Attributes */
2850         offset = dissect_search_attributes(tvb, tree, offset);
2851
2852         BYTE_COUNT;
2853
2854         /* buffer format */
2855         CHECK_BYTE_COUNT(1);
2856         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2857         COUNT_BYTES(1);
2858
2859         /* file name */
2860         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2861                 FALSE, FALSE, &bc);
2862         if (fn == NULL)
2863                 goto endofcommand;
2864         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2865                 fn);
2866         COUNT_BYTES(fn_len);
2867
2868         if (check_col(pinfo->cinfo, COL_INFO)) {
2869                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2870         }
2871
2872         END_OF_SMB
2873
2874         return offset;
2875 }
2876
2877 void
2878 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2879     int len, guint16 fid)
2880 {
2881         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2882         if (check_col(pinfo->cinfo, COL_INFO))
2883                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2884 }
2885
2886 static int
2887 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2888 {
2889         guint8 wc;
2890         guint16 bc;
2891         guint16 fid;
2892
2893         WORD_COUNT;
2894
2895         /* fid */
2896         fid = tvb_get_letohs(tvb, offset);
2897         add_fid(tvb, pinfo, tree, offset, 2, fid);
2898         offset += 2;
2899
2900         /* File Attributes */
2901         offset = dissect_file_attributes(tvb, tree, offset, 2);
2902
2903         /* last write time */
2904         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2905
2906         /* File Size */
2907         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2908         offset += 4;
2909
2910         /* granted access */
2911         offset = dissect_access(tvb, tree, offset, "Granted");
2912
2913         BYTE_COUNT;
2914
2915         END_OF_SMB
2916
2917         return offset;
2918 }
2919
2920 static int
2921 dissect_fid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2922 {
2923         guint8 wc;
2924         guint16 bc;
2925         guint16 fid;
2926
2927         WORD_COUNT;
2928
2929         /* fid */
2930         fid = tvb_get_letohs(tvb, offset);
2931         add_fid(tvb, pinfo, tree, offset, 2, fid);
2932         offset += 2;
2933
2934         BYTE_COUNT;
2935
2936         END_OF_SMB
2937
2938         return offset;
2939 }
2940
2941 static int
2942 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2943 {
2944         smb_info_t *si = pinfo->private_data;
2945         int fn_len;
2946         const char *fn;
2947         guint8 wc;
2948         guint16 bc;
2949
2950         WORD_COUNT;
2951
2952         /* file attributes */
2953         offset = dissect_file_attributes(tvb, tree, offset, 2);
2954
2955         /* creation time */
2956         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
2957
2958         BYTE_COUNT;
2959
2960         /* buffer format */
2961         CHECK_BYTE_COUNT(1);
2962         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2963         COUNT_BYTES(1);
2964
2965         /* File Name */
2966         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2967                 FALSE, FALSE, &bc);
2968         if (fn == NULL)
2969                 goto endofcommand;
2970         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2971                 fn);
2972         COUNT_BYTES(fn_len);
2973
2974         if (check_col(pinfo->cinfo, COL_INFO)) {
2975                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2976         }
2977
2978         END_OF_SMB
2979
2980         return offset;
2981 }
2982
2983 static int
2984 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2985 {
2986         guint8 wc;
2987         guint16 bc, fid;
2988
2989         WORD_COUNT;
2990
2991         /* fid */
2992         fid = tvb_get_letohs(tvb, offset);
2993         add_fid(tvb, pinfo, tree, offset, 2, fid);
2994         offset += 2;
2995
2996         /* last write time */
2997         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2998
2999         BYTE_COUNT;
3000
3001         END_OF_SMB
3002
3003         return offset;
3004 }
3005
3006 static int
3007 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3008 {
3009         smb_info_t *si = pinfo->private_data;
3010         int fn_len;
3011         const char *fn;
3012         guint8 wc;
3013         guint16 bc;
3014
3015         WORD_COUNT;
3016
3017         /* search attributes */
3018         offset = dissect_search_attributes(tvb, tree, offset);
3019
3020         BYTE_COUNT;
3021
3022         /* buffer format */
3023         CHECK_BYTE_COUNT(1);
3024         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3025         COUNT_BYTES(1);
3026
3027         /* file name */
3028         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3029                 FALSE, FALSE, &bc);
3030         if (fn == NULL)
3031                 goto endofcommand;
3032         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3033                 fn);
3034         COUNT_BYTES(fn_len);
3035
3036         if (check_col(pinfo->cinfo, COL_INFO)) {
3037                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3038         }
3039
3040         END_OF_SMB
3041
3042         return offset;
3043 }
3044
3045 static int
3046 dissect_rename_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         /* old 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_old_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, ", Old Name: %s", fn);
3077         }
3078
3079         /* buffer format */
3080         CHECK_BYTE_COUNT(1);
3081         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3082         COUNT_BYTES(1);
3083
3084         /* file name */
3085         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3086                 FALSE, FALSE, &bc);
3087         if (fn == NULL)
3088                 goto endofcommand;
3089         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3090                 fn);
3091         COUNT_BYTES(fn_len);
3092
3093         if (check_col(pinfo->cinfo, COL_INFO)) {
3094                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3095         }
3096
3097         END_OF_SMB
3098
3099         return offset;
3100 }
3101
3102 static int
3103 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3104 {
3105         smb_info_t *si = pinfo->private_data;
3106         int fn_len;
3107         const char *fn;
3108         guint8 wc;
3109         guint16 bc;
3110
3111         WORD_COUNT;
3112
3113         /* search attributes */
3114         offset = dissect_search_attributes(tvb, tree, offset);
3115
3116         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3117         offset += 2;
3118
3119         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3120         offset += 4;
3121
3122         BYTE_COUNT;
3123
3124         /* buffer format */
3125         CHECK_BYTE_COUNT(1);
3126         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3127         COUNT_BYTES(1);
3128
3129         /* old file name */
3130         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3131                 FALSE, FALSE, &bc);
3132         if (fn == NULL)
3133                 goto endofcommand;
3134         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3135                 fn);
3136         COUNT_BYTES(fn_len);
3137
3138         if (check_col(pinfo->cinfo, COL_INFO)) {
3139                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3140         }
3141
3142         /* buffer format */
3143         CHECK_BYTE_COUNT(1);
3144         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3145         COUNT_BYTES(1);
3146
3147         /* file name */
3148         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3149                 FALSE, FALSE, &bc);
3150         if (fn == NULL)
3151                 goto endofcommand;
3152         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3153                 fn);
3154         COUNT_BYTES(fn_len);
3155
3156         if (check_col(pinfo->cinfo, COL_INFO)) {
3157                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3158         }
3159
3160         END_OF_SMB
3161
3162         return offset;
3163 }
3164
3165
3166 static int
3167 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3168 {
3169         smb_info_t *si = pinfo->private_data;
3170         guint16 bc;
3171         guint8 wc;
3172         const char *fn;
3173         int fn_len;
3174
3175         WORD_COUNT;
3176
3177         BYTE_COUNT;
3178
3179         /* Buffer Format */
3180         CHECK_BYTE_COUNT(1);
3181         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3182         COUNT_BYTES(1);
3183
3184         /* File Name */
3185         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3186                 FALSE, FALSE, &bc);
3187         if (fn == NULL)
3188                 goto endofcommand;
3189         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3190                 fn);
3191         COUNT_BYTES(fn_len);
3192
3193         if (check_col(pinfo->cinfo, COL_INFO)) {
3194                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3195         }
3196
3197         END_OF_SMB
3198
3199         return offset;
3200 }
3201
3202 static int
3203 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3204 {
3205         guint16 bc;
3206         guint8 wc;
3207
3208         WORD_COUNT;
3209
3210         /* File Attributes */
3211         offset = dissect_file_attributes(tvb, tree, offset, 2);
3212
3213         /* Last Write Time */
3214         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3215
3216         /* File Size */
3217         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3218         offset += 4;
3219
3220         /* 10 reserved bytes */
3221         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3222         offset += 10;
3223
3224         BYTE_COUNT;
3225
3226         END_OF_SMB
3227
3228         return offset;
3229 }
3230
3231 static int
3232 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3233 {
3234         smb_info_t *si = pinfo->private_data;
3235         int fn_len;
3236         const char *fn;
3237         guint8 wc;
3238         guint16 bc;
3239
3240         WORD_COUNT;
3241
3242         /* file attributes */
3243         offset = dissect_file_attributes(tvb, tree, offset, 2);
3244
3245         /* last write time */
3246         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3247
3248         /* 10 reserved bytes */
3249         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3250         offset += 10;
3251
3252         BYTE_COUNT;
3253
3254         /* buffer format */
3255         CHECK_BYTE_COUNT(1);
3256         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3257         COUNT_BYTES(1);
3258
3259         /* file name */
3260         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3261                 FALSE, FALSE, &bc);
3262         if (fn == NULL)
3263                 goto endofcommand;
3264         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3265                 fn);
3266         COUNT_BYTES(fn_len);
3267
3268         if (check_col(pinfo->cinfo, COL_INFO)) {
3269                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3270         }
3271
3272         END_OF_SMB
3273
3274         return offset;
3275 }
3276
3277 static int
3278 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3279 {
3280         guint8 wc;
3281         guint16 cnt=0, bc;
3282         guint32 ofs=0;
3283         smb_info_t *si;
3284         unsigned int fid;
3285
3286         WORD_COUNT;
3287
3288         /* fid */
3289         fid = tvb_get_letohs(tvb, offset);
3290         add_fid(tvb, pinfo, tree, offset, 2, fid);
3291         offset += 2;
3292         if (!pinfo->fd->flags.visited) {
3293                 /* remember the FID for the processing of the response */
3294                 si = (smb_info_t *)pinfo->private_data;
3295                 si->sip->extra_info=(void *)fid;
3296         }
3297
3298         /* read count */
3299         cnt = tvb_get_letohs(tvb, offset);
3300         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3301         offset += 2;
3302
3303         /* offset */
3304         ofs = tvb_get_letohl(tvb, offset);
3305         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3306         offset += 4;
3307
3308         if (check_col(pinfo->cinfo, COL_INFO))
3309                 col_append_fstr(pinfo->cinfo, COL_INFO,
3310                                 ", %u byte%s at offset %u", cnt,
3311                                 (cnt == 1) ? "" : "s", ofs);
3312
3313         /* remaining */
3314         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3315         offset += 2;
3316
3317         BYTE_COUNT;
3318
3319         END_OF_SMB
3320
3321         return offset;
3322 }
3323
3324 int
3325 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3326 {
3327         int tvblen;
3328
3329         if(bc>datalen){
3330                 /* We have some initial padding bytes. */
3331                 /* XXX - use the data offset here instead? */
3332                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3333                         TRUE);
3334                 offset += bc-datalen;
3335                 bc = datalen;
3336         }
3337         tvblen = tvb_length_remaining(tvb, offset);
3338         if(bc>tvblen){
3339                 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);
3340                 offset += tvblen;
3341         } else {
3342                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3343                 offset += bc;
3344         }
3345         return offset;
3346 }
3347
3348 static int
3349 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3350     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
3351 {
3352         int tvblen;
3353         tvbuff_t *dcerpc_tvb;
3354
3355         if(bc>datalen){
3356                 /* We have some initial padding bytes. */
3357                 /* XXX - use the data offset here instead? */
3358                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3359                         TRUE);
3360                 offset += bc-datalen;
3361                 bc = datalen;
3362         }
3363         tvblen = tvb_length_remaining(tvb, offset);
3364         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
3365         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
3366         if(bc>tvblen)
3367                 offset += tvblen;
3368         else
3369                 offset += bc;
3370         return offset;
3371 }
3372
3373 /*
3374  * transporting DCERPC over SMB seems to be implemented in various
3375  * ways. We might just assume it can be done by an almost random
3376  * mix of Trans/Read/Write calls
3377  *
3378  * if we suspect dcerpc, just send them all down to packet-smb-pipe.c
3379  * and let him sort them out
3380  */
3381 static int
3382 dissect_file_data_maybe_dcerpc(tvbuff_t *tvb, packet_info *pinfo,
3383     proto_tree *tree, proto_tree *top_tree, int offset, guint16 bc,
3384     guint16 datalen, guint32 ofs, guint16 fid)
3385 {
3386         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3387
3388         if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
3389                 /* dcerpc call */
3390                 return dissect_file_data_dcerpc(tvb, pinfo, tree,
3391                     top_tree, offset, bc, datalen, fid);
3392         } else {
3393                 /* ordinary file data */
3394                 return dissect_file_data(tvb, tree, offset, bc, datalen);
3395         }
3396 }
3397
3398 static int
3399 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3400 {
3401         guint16 cnt=0, bc;
3402         guint8 wc;
3403         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3404         int fid=0;
3405
3406         WORD_COUNT;
3407
3408         /* read count */
3409         cnt = tvb_get_letohs(tvb, offset);
3410         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3411         offset += 2;
3412
3413         /* 8 reserved bytes */
3414         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3415         offset += 8;
3416
3417         /* If we have seen the request, then print which FID this refers to */
3418         /* first check if we have seen the request */
3419         if(si->sip != NULL && si->sip->frame_req>0){
3420                 fid=(int)si->sip->extra_info;
3421                 add_fid(tvb, pinfo, tree, 0, 0, fid);
3422         }
3423
3424         BYTE_COUNT;
3425
3426         /* buffer format */
3427         CHECK_BYTE_COUNT(1);
3428         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3429         COUNT_BYTES(1);
3430
3431         /* data len */
3432         CHECK_BYTE_COUNT(2);
3433         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3434         COUNT_BYTES(2);
3435
3436         /* file data, might be DCERPC on a pipe */
3437         if(bc){
3438                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3439                     top_tree, offset, bc, bc, 0, fid);
3440                 bc = 0;
3441         }
3442
3443         END_OF_SMB
3444
3445         return offset;
3446 }
3447
3448 static int
3449 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3450 {
3451         guint16 cnt, bc;
3452         guint8 wc;
3453
3454         WORD_COUNT;
3455
3456         /* read count */
3457         cnt = tvb_get_letohs(tvb, offset);
3458         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3459         offset += 2;
3460
3461         /* 8 reserved bytes */
3462         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3463         offset += 8;
3464
3465         BYTE_COUNT;
3466
3467         /* buffer format */
3468         CHECK_BYTE_COUNT(1);
3469         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3470         COUNT_BYTES(1);
3471
3472         /* data len */
3473         CHECK_BYTE_COUNT(2);
3474         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3475         COUNT_BYTES(2);
3476
3477         END_OF_SMB
3478
3479         return offset;
3480 }
3481
3482
3483 static int
3484 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3485 {
3486         guint32 ofs=0;
3487         guint16 cnt=0, bc, fid=0;
3488         guint8 wc;
3489
3490         WORD_COUNT;
3491
3492         /* fid */
3493         fid = tvb_get_letohs(tvb, offset);
3494         add_fid(tvb, pinfo, tree, offset, 2, fid);
3495         offset += 2;
3496
3497         /* write count */
3498         cnt = tvb_get_letohs(tvb, offset);
3499         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3500         offset += 2;
3501
3502         /* offset */
3503         ofs = tvb_get_letohl(tvb, offset);
3504         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3505         offset += 4;
3506
3507         if (check_col(pinfo->cinfo, COL_INFO))
3508                 col_append_fstr(pinfo->cinfo, COL_INFO,
3509                                 ", %u byte%s at offset %u", cnt,
3510                                 (cnt == 1) ? "" : "s", ofs);
3511
3512         /* remaining */
3513         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3514         offset += 2;
3515
3516         BYTE_COUNT;
3517
3518         /* buffer format */
3519         CHECK_BYTE_COUNT(1);
3520         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3521         COUNT_BYTES(1);
3522
3523         /* data len */
3524         CHECK_BYTE_COUNT(2);
3525         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3526         COUNT_BYTES(2);
3527
3528         /* file data, might be DCERPC on a pipe */
3529         if (bc != 0) {
3530                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3531                     top_tree, offset, bc, bc, ofs, fid);
3532                 bc = 0;
3533         }
3534
3535         END_OF_SMB
3536
3537         return offset;
3538 }
3539
3540 static int
3541 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3542 {
3543         guint8 wc;
3544         guint16 bc, cnt;
3545
3546         WORD_COUNT;
3547
3548         /* write count */
3549         cnt = tvb_get_letohs(tvb, offset);
3550         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3551         offset += 2;
3552
3553         if (check_col(pinfo->cinfo, COL_INFO))
3554                 col_append_fstr(pinfo->cinfo, COL_INFO,
3555                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
3556
3557         BYTE_COUNT;
3558
3559         END_OF_SMB
3560
3561         return offset;
3562 }
3563
3564 static int
3565 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3566 {
3567         guint8 wc;
3568         guint16 bc, fid;
3569
3570         WORD_COUNT;
3571
3572         /* fid */
3573         fid = tvb_get_letohs(tvb, offset);
3574         add_fid(tvb, pinfo, tree, offset, 2, fid);
3575         offset += 2;
3576
3577         /* lock count */
3578         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3579         offset += 4;
3580
3581         /* offset */
3582         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3583         offset += 4;
3584
3585         BYTE_COUNT;
3586
3587         END_OF_SMB
3588
3589         return offset;
3590 }
3591
3592 static int
3593 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3594 {
3595         smb_info_t *si = pinfo->private_data;
3596         int fn_len;
3597         const char *fn;
3598         guint8 wc;
3599         guint16 bc;
3600
3601         WORD_COUNT;
3602
3603         /* 2 reserved bytes */
3604         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3605         offset += 2;
3606
3607         /* Creation time */
3608         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3609
3610         BYTE_COUNT;
3611
3612         /* buffer format */
3613         CHECK_BYTE_COUNT(1);
3614         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3615         COUNT_BYTES(1);
3616
3617         /* directory name */
3618         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3619                 FALSE, FALSE, &bc);
3620         if (fn == NULL)
3621                 goto endofcommand;
3622         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3623                 fn);
3624         COUNT_BYTES(fn_len);
3625
3626         if (check_col(pinfo->cinfo, COL_INFO)) {
3627                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3628         }
3629
3630         END_OF_SMB
3631
3632         return offset;
3633 }
3634
3635 static int
3636 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3637 {
3638         smb_info_t *si = pinfo->private_data;
3639         int fn_len;
3640         const char *fn;
3641         guint8 wc;
3642         guint16 bc, fid;
3643
3644         WORD_COUNT;
3645
3646         /* fid */
3647         fid = tvb_get_letohs(tvb, offset);
3648         add_fid(tvb, pinfo, tree, offset, 2, fid);
3649         offset += 2;
3650
3651         BYTE_COUNT;
3652
3653         /* buffer format */
3654         CHECK_BYTE_COUNT(1);
3655         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3656         COUNT_BYTES(1);
3657
3658         /* file name */
3659         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3660                 FALSE, FALSE, &bc);
3661         if (fn == NULL)
3662                 goto endofcommand;
3663         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3664                 fn);
3665         COUNT_BYTES(fn_len);
3666
3667         END_OF_SMB
3668
3669         return offset;
3670 }
3671
3672 static const value_string seek_mode_vals[] = {
3673         {0,     "From Start Of File"},
3674         {1,     "From Current Position"},
3675         {2,     "From End Of File"},
3676         {0,     NULL}
3677 };
3678
3679 static int
3680 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3681 {
3682         guint8 wc;
3683         guint16 bc, fid;
3684
3685         WORD_COUNT;
3686
3687         /* fid */
3688         fid = tvb_get_letohs(tvb, offset);
3689         add_fid(tvb, pinfo, tree, offset, 2, fid);
3690         offset += 2;
3691
3692         /* Seek Mode */
3693         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3694         offset += 2;
3695
3696         /* offset */
3697         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3698         offset += 4;
3699
3700         BYTE_COUNT;
3701
3702         END_OF_SMB
3703
3704         return offset;
3705 }
3706
3707 static int
3708 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3709 {
3710         guint8 wc;
3711         guint16 bc;
3712
3713         WORD_COUNT;
3714
3715         /* offset */
3716         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3717         offset += 4;
3718
3719         BYTE_COUNT;
3720
3721         END_OF_SMB
3722
3723         return offset;
3724 }
3725
3726 static int
3727 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3728 {
3729         guint8 wc;
3730         guint16 bc, fid;
3731
3732         WORD_COUNT;
3733
3734         /* fid */
3735         fid = tvb_get_letohs(tvb, offset);
3736         add_fid(tvb, pinfo, tree, offset, 2, fid);
3737         offset += 2;
3738
3739         /* create time */
3740         offset = dissect_smb_datetime(tvb, tree, offset,
3741                 hf_smb_create_time,
3742                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3743
3744         /* access time */
3745         offset = dissect_smb_datetime(tvb, tree, offset,
3746                 hf_smb_access_time,
3747                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3748
3749         /* last write time */
3750         offset = dissect_smb_datetime(tvb, tree, offset,
3751                 hf_smb_last_write_time,
3752                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3753
3754         BYTE_COUNT;
3755
3756         END_OF_SMB
3757
3758         return offset;
3759 }
3760
3761 static int
3762 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3763 {
3764         guint8 wc;
3765         guint16 bc;
3766
3767         WORD_COUNT;
3768
3769         /* create time */
3770         offset = dissect_smb_datetime(tvb, tree, offset,
3771                 hf_smb_create_time,
3772                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3773
3774         /* access time */
3775         offset = dissect_smb_datetime(tvb, tree, offset,
3776                 hf_smb_access_time,
3777                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3778
3779         /* last write time */
3780         offset = dissect_smb_datetime(tvb, tree, offset,
3781                 hf_smb_last_write_time,
3782                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3783
3784         /* data size */
3785         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3786         offset += 4;
3787
3788         /* allocation size */
3789         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3790         offset += 4;
3791
3792         /* File Attributes */
3793         offset = dissect_file_attributes(tvb, tree, offset, 2);
3794
3795         BYTE_COUNT;
3796
3797         END_OF_SMB
3798
3799         return offset;
3800 }
3801
3802 static int
3803 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3804 {
3805         guint8 wc;
3806         guint16 cnt=0;
3807         guint16 bc, fid;
3808
3809         WORD_COUNT;
3810
3811         /* fid */
3812         fid = tvb_get_letohs(tvb, offset);
3813         add_fid(tvb, pinfo, tree, offset, 2, fid);
3814         offset += 2;
3815
3816         /* write count */
3817         cnt = tvb_get_letohs(tvb, offset);
3818         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3819         offset += 2;
3820
3821         /* offset */
3822         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3823         offset += 4;
3824
3825         /* last write time */
3826         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3827
3828         if(wc==12){
3829                 /* 12 reserved bytes */
3830                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3831                 offset += 12;
3832         }
3833
3834         BYTE_COUNT;
3835
3836         /* 1 pad byte */
3837         CHECK_BYTE_COUNT(1);
3838         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3839         COUNT_BYTES(1);
3840
3841         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
3842         bc = 0; /* XXX */
3843
3844         END_OF_SMB
3845
3846         return offset;
3847 }
3848
3849 static int
3850 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3851 {
3852         guint8 wc;
3853         guint16 bc;
3854
3855         WORD_COUNT;
3856
3857         /* write count */
3858         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3859         offset += 2;
3860
3861         BYTE_COUNT;
3862
3863         END_OF_SMB
3864
3865         return offset;
3866 }
3867
3868 static int
3869 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3870 {
3871         guint8 wc;
3872         guint16 bc, fid;
3873         guint32 to;
3874
3875         WORD_COUNT;
3876
3877         /* fid */
3878         fid = tvb_get_letohs(tvb, offset);
3879         add_fid(tvb, pinfo, tree, offset, 2, fid);
3880         offset += 2;
3881
3882         /* offset */
3883         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3884         offset += 4;
3885
3886         /* max count */
3887         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3888         offset += 2;
3889
3890         /* min count */
3891         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3892         offset += 2;
3893
3894         /* timeout */
3895         to = tvb_get_letohl(tvb, offset);
3896         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3897         offset += 4;
3898
3899         /* 2 reserved bytes */
3900         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3901         offset += 2;
3902
3903         if(wc==10){
3904                 /* high offset */
3905                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3906                 offset += 4;
3907         }
3908
3909         BYTE_COUNT;
3910
3911         END_OF_SMB
3912
3913         return offset;
3914 }
3915
3916 static int
3917 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3918 {
3919         guint8 wc;
3920         guint16 bc;
3921
3922         WORD_COUNT;
3923
3924         /* units */
3925         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3926         offset += 2;
3927
3928         /* bpu */
3929         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3930         offset += 2;
3931
3932         /* block size */
3933         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3934         offset += 2;
3935
3936         /* free units */
3937         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3938         offset += 2;
3939
3940         /* 2 reserved bytes */
3941         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3942         offset += 2;
3943
3944         BYTE_COUNT;
3945
3946         END_OF_SMB
3947
3948         return offset;
3949 }
3950
3951 static int
3952 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3953 {
3954         guint8 wc;
3955         guint16 bc, fid;
3956
3957         WORD_COUNT;
3958
3959         /* fid */
3960         fid = tvb_get_letohs(tvb, offset);
3961         add_fid(tvb, pinfo, tree, offset, 2, fid);
3962         offset += 2;
3963
3964         /* offset */
3965         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3966         offset += 4;
3967
3968         /* max count */
3969         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3970         offset += 2;
3971
3972         /* min count */
3973         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3974         offset += 2;
3975
3976         /* 6 reserved bytes */
3977         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
3978         offset += 6;
3979
3980         BYTE_COUNT;
3981
3982         END_OF_SMB
3983
3984         return offset;
3985 }
3986
3987 static int
3988 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3989 {
3990         guint16 datalen=0, bc;
3991         guint8 wc;
3992
3993         WORD_COUNT;
3994
3995         /* offset */
3996         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3997         offset += 4;
3998
3999         /* count */
4000         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4001         offset += 2;
4002
4003         /* 2 reserved bytes */
4004         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4005         offset += 2;
4006
4007         /* data compaction mode */
4008         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4009         offset += 2;
4010
4011         /* 2 reserved bytes */
4012         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4013         offset += 2;
4014
4015         /* data len */
4016         datalen = tvb_get_letohs(tvb, offset);
4017         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4018         offset += 2;
4019
4020         /* data offset */
4021         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4022         offset += 2;
4023
4024         BYTE_COUNT;
4025
4026         /* file data */
4027         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4028         bc = 0;
4029
4030         END_OF_SMB
4031
4032         return offset;
4033 }
4034
4035
4036 static const true_false_string tfs_write_mode_write_through = {
4037         "WRITE THROUGH requested",
4038         "Write through not requested"
4039 };
4040 static const true_false_string tfs_write_mode_return_remaining = {
4041         "RETURN REMAINING (pipe/dev) requested",
4042         "DON'T return remaining (pipe/dev)"
4043 };
4044 static const true_false_string tfs_write_mode_raw = {
4045         "Use WriteRawNamedPipe (pipe)",
4046         "DON'T use WriteRawNamedPipe (pipe)"
4047 };
4048 static const true_false_string tfs_write_mode_message_start = {
4049         "This is the START of a MESSAGE (pipe)",
4050         "This is NOT the start of a message (pipe)"
4051 };
4052 static const true_false_string tfs_write_mode_connectionless = {
4053         "CONNECTIONLESS mode requested",
4054         "Connectionless mode NOT requested"
4055 };
4056
4057 #define WRITE_MODE_CONNECTIONLESS       0x0080
4058 #define WRITE_MODE_MESSAGE_START        0x0008
4059 #define WRITE_MODE_RAW                  0x0004
4060 #define WRITE_MODE_RETURN_REMAINING     0x0002
4061 #define WRITE_MODE_WRITE_THROUGH        0x0001
4062
4063 static int
4064 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4065 {
4066         guint16 mask;
4067         proto_item *item = NULL;
4068         proto_tree *tree = NULL;
4069
4070         mask = tvb_get_letohs(tvb, offset);
4071
4072         if(parent_tree){
4073                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4074                         "Write Mode: 0x%04x", mask);
4075                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
4076         }
4077
4078         if(bm&WRITE_MODE_CONNECTIONLESS){
4079                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
4080                         tvb, offset, 2, mask);
4081         }
4082         if(bm&WRITE_MODE_MESSAGE_START){
4083                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
4084                         tvb, offset, 2, mask);
4085         }
4086         if(bm&WRITE_MODE_RAW){
4087                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
4088                         tvb, offset, 2, mask);
4089         }
4090         if(bm&WRITE_MODE_RETURN_REMAINING){
4091                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
4092                         tvb, offset, 2, mask);
4093         }
4094         if(bm&WRITE_MODE_WRITE_THROUGH){
4095                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4096                         tvb, offset, 2, mask);
4097         }
4098
4099         offset += 2;
4100         return offset;
4101 }
4102
4103 static int
4104 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4105 {
4106         guint32 to;
4107         guint16 datalen=0, bc, fid;
4108         guint8 wc;
4109
4110         WORD_COUNT;
4111
4112         /* fid */
4113         fid = tvb_get_letohs(tvb, offset);
4114         add_fid(tvb, pinfo, tree, offset, 2, fid);
4115         offset += 2;
4116
4117         /* total data length */
4118         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4119         offset += 2;
4120
4121         /* 2 reserved bytes */
4122         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4123         offset += 2;
4124
4125         /* offset */
4126         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4127         offset += 4;
4128
4129         /* timeout */
4130         to = tvb_get_letohl(tvb, offset);
4131         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4132         offset += 4;
4133
4134         /* mode */
4135         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4136
4137         /* 4 reserved bytes */
4138         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4139         offset += 4;
4140
4141         /* data len */
4142         datalen = tvb_get_letohs(tvb, offset);
4143         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4144         offset += 2;
4145
4146         /* data offset */
4147         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4148         offset += 2;
4149
4150         BYTE_COUNT;
4151
4152         /* file data */
4153         /* XXX - use the data offset to determine where the data starts? */
4154         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4155         bc = 0;
4156
4157         END_OF_SMB
4158
4159         return offset;
4160 }
4161
4162 static int
4163 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4164 {
4165         guint8 wc;
4166         guint16 bc;
4167
4168         WORD_COUNT;
4169
4170         /* remaining */
4171         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4172         offset += 2;
4173
4174         BYTE_COUNT;
4175
4176         END_OF_SMB
4177
4178         return offset;
4179 }
4180
4181 static int
4182 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4183 {
4184         guint32 to;
4185         guint16 datalen=0, bc, fid;
4186         guint8 wc;
4187
4188         WORD_COUNT;
4189
4190         /* fid */
4191         fid = tvb_get_letohs(tvb, offset);
4192         add_fid(tvb, pinfo, tree, offset, 2, fid);
4193         offset += 2;
4194
4195         /* total data length */
4196         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4197         offset += 2;
4198
4199         /* 2 reserved bytes */
4200         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4201         offset += 2;
4202
4203         /* offset */
4204         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4205         offset += 4;
4206
4207         /* timeout */
4208         to = tvb_get_letohl(tvb, offset);
4209         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4210         offset += 4;
4211
4212         /* mode */
4213         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
4214
4215         /* request mask */
4216         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
4217         offset += 4;
4218
4219         /* data len */
4220         datalen = tvb_get_letohs(tvb, offset);
4221         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4222         offset += 2;
4223
4224         /* data offset */
4225         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4226         offset += 2;
4227
4228         BYTE_COUNT;
4229
4230         /* file data */
4231         /* XXX - use the data offset to determine where the data starts? */
4232         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4233         bc = 0;
4234
4235         END_OF_SMB
4236
4237         return offset;
4238 }
4239
4240 static int
4241 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4242 {
4243         guint8 wc;
4244         guint16 bc;
4245
4246         WORD_COUNT;
4247
4248         /* response mask */
4249         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
4250         offset += 4;
4251
4252         BYTE_COUNT;
4253
4254         END_OF_SMB
4255
4256         return offset;
4257 }
4258
4259 static int
4260 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4261 {
4262         guint8 wc;
4263         guint16 bc;
4264
4265         WORD_COUNT;
4266
4267         /* sid */
4268         proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
4269         offset += 2;
4270
4271         BYTE_COUNT;
4272
4273         END_OF_SMB
4274
4275         return offset;
4276 }
4277
4278 static int
4279 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
4280     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4281     gboolean has_find_id)
4282 {
4283         proto_item *item = NULL;
4284         proto_tree *tree = NULL;
4285         smb_info_t *si = pinfo->private_data;
4286         int fn_len;
4287         const char *fn;
4288         char fname[11+1];
4289
4290         if(parent_tree){
4291                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
4292                         "Resume Key");
4293                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
4294         }
4295
4296         /* reserved byte */
4297         CHECK_BYTE_COUNT_SUBR(1);
4298         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4299         COUNT_BYTES_SUBR(1);
4300
4301         /* file name */
4302         fn_len = 11;
4303         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4304                 TRUE, TRUE, bcp);
4305         CHECK_STRING_SUBR(fn);
4306         /* ensure that it's null-terminated */
4307         strncpy(fname, fn, 11);
4308         fname[11] = '\0';
4309         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
4310                 fname);
4311         COUNT_BYTES_SUBR(fn_len);
4312
4313         if (has_find_id) {
4314                 CHECK_BYTE_COUNT_SUBR(1);
4315                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
4316                 COUNT_BYTES_SUBR(1);
4317
4318                 /* server cookie */
4319                 CHECK_BYTE_COUNT_SUBR(4);
4320                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
4321                 COUNT_BYTES_SUBR(4);
4322         } else {
4323                 /* server cookie */
4324                 CHECK_BYTE_COUNT_SUBR(5);
4325                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
4326                 COUNT_BYTES_SUBR(5);
4327         }
4328
4329         /* client cookie */
4330         CHECK_BYTE_COUNT_SUBR(4);
4331         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
4332         COUNT_BYTES_SUBR(4);
4333
4334         *trunc = FALSE;
4335         return offset;
4336 }
4337
4338 static int
4339 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
4340     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4341     gboolean has_find_id)
4342 {
4343         proto_item *item = NULL;
4344         proto_tree *tree = NULL;
4345         smb_info_t *si = pinfo->private_data;
4346         int fn_len;
4347         const char *fn;
4348         char fname[13+1];
4349
4350         if(parent_tree){
4351                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
4352                         "Directory Information");
4353                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
4354         }
4355
4356         /* resume key */
4357         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
4358             trunc, has_find_id);
4359         if (*trunc)
4360                 return offset;
4361
4362         /* File Attributes */
4363         CHECK_BYTE_COUNT_SUBR(1);
4364         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
4365         *bcp -= 1;
4366
4367         /* last write time */
4368         CHECK_BYTE_COUNT_SUBR(4);
4369         offset = dissect_smb_datetime(tvb, tree, offset,
4370                 hf_smb_last_write_time,
4371                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
4372                 TRUE);
4373         *bcp -= 4;
4374
4375         /* File Size */
4376         CHECK_BYTE_COUNT_SUBR(4);
4377         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4378         COUNT_BYTES_SUBR(4);
4379
4380         /* file name */
4381         fn_len = 13;
4382         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4383                 TRUE, TRUE, bcp);
4384         CHECK_STRING_SUBR(fn);
4385         /* ensure that it's null-terminated */
4386         strncpy(fname, fn, 13);
4387         fname[13] = '\0';
4388         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4389                 fname);
4390         COUNT_BYTES_SUBR(fn_len);
4391
4392         *trunc = FALSE;
4393         return offset;
4394 }
4395
4396
4397 static int
4398 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
4399     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4400     gboolean has_find_id)
4401 {
4402         smb_info_t *si = pinfo->private_data;
4403         int fn_len;
4404         const char *fn;
4405         guint16 rkl;
4406         guint8 wc;
4407         guint16 bc;
4408         gboolean trunc;
4409
4410         WORD_COUNT;
4411
4412         /* max count */
4413         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4414         offset += 2;
4415
4416         /* Search Attributes */
4417         offset = dissect_search_attributes(tvb, tree, offset);
4418
4419         BYTE_COUNT;
4420
4421         /* buffer format */
4422         CHECK_BYTE_COUNT(1);
4423         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4424         COUNT_BYTES(1);
4425
4426         /* file name */
4427         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4428                 TRUE, FALSE, &bc);
4429         if (fn == NULL)
4430                 goto endofcommand;
4431         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4432                 fn);
4433         COUNT_BYTES(fn_len);
4434
4435         if (check_col(pinfo->cinfo, COL_INFO)) {
4436                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", fn);
4437         }
4438
4439         /* buffer format */
4440         CHECK_BYTE_COUNT(1);
4441         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4442         COUNT_BYTES(1);
4443
4444         /* resume key length */
4445         CHECK_BYTE_COUNT(2);
4446         rkl = tvb_get_letohs(tvb, offset);
4447         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
4448         COUNT_BYTES(2);
4449
4450         /* resume key */
4451         if(rkl){
4452                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
4453                     &bc, &trunc, has_find_id);
4454                 if (trunc)
4455                         goto endofcommand;
4456         }
4457
4458         END_OF_SMB
4459
4460         return offset;
4461 }
4462
4463 static int
4464 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4465     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4466 {
4467         return dissect_search_find_request(tvb, pinfo, tree, offset,
4468             smb_tree, FALSE);
4469 }
4470
4471 static int
4472 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4473     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4474 {
4475         return dissect_search_find_request(tvb, pinfo, tree, offset,
4476             smb_tree, TRUE);
4477 }
4478
4479 static int
4480 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4481     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4482 {
4483         return dissect_search_find_request(tvb, pinfo, tree, offset,
4484             smb_tree, TRUE);
4485 }
4486
4487 static int
4488 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4489     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4490     gboolean has_find_id)
4491 {
4492         guint16 count=0;
4493         guint8 wc;
4494         guint16 bc;
4495         gboolean trunc;
4496
4497         WORD_COUNT;
4498
4499         /* count */
4500         count = tvb_get_letohs(tvb, offset);
4501         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
4502         offset += 2;
4503
4504         BYTE_COUNT;
4505
4506         /* buffer format */
4507         CHECK_BYTE_COUNT(1);
4508         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4509         COUNT_BYTES(1);
4510
4511         /* data len */
4512         CHECK_BYTE_COUNT(2);
4513         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4514         COUNT_BYTES(2);
4515
4516         while(count--){
4517                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
4518                     &bc, &trunc, has_find_id);
4519                 if (trunc)
4520                         goto endofcommand;
4521         }
4522
4523         END_OF_SMB
4524
4525         return offset;
4526 }
4527
4528 static int
4529 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4530 {
4531         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4532             FALSE);
4533 }
4534
4535 static int
4536 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4537 {
4538         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4539             TRUE);
4540 }
4541
4542 static int
4543 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4544     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4545 {
4546         guint8 wc;
4547         guint16 bc;
4548         guint16 data_len;
4549
4550         WORD_COUNT;
4551
4552         /* reserved */
4553         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4554         offset += 2;
4555
4556         BYTE_COUNT;
4557
4558         /* buffer format */
4559         CHECK_BYTE_COUNT(1);
4560         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4561         COUNT_BYTES(1);
4562
4563         /* data len */
4564         CHECK_BYTE_COUNT(2);
4565         data_len = tvb_get_ntohs(tvb, offset);
4566         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
4567         COUNT_BYTES(2);
4568
4569         if (data_len != 0) {
4570                 CHECK_BYTE_COUNT(data_len);
4571                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
4572                     data_len, TRUE);
4573                 COUNT_BYTES(data_len);
4574         }
4575
4576         END_OF_SMB
4577
4578         return offset;
4579 }
4580
4581 static const value_string locking_ol_vals[] = {
4582         {0,     "Client is not holding oplock on this file"},
4583         {1,     "Level 2 oplock currently held by client"},
4584         {0, NULL}
4585 };
4586
4587 static const true_false_string tfs_lock_type_large = {
4588         "Large file locking format requested",
4589         "Large file locking format not requested"
4590 };
4591 static const true_false_string tfs_lock_type_cancel = {
4592         "Cancel outstanding lock request",
4593         "Don't cancel outstanding lock request"
4594 };
4595 static const true_false_string tfs_lock_type_change = {
4596         "Change lock type",
4597         "Don't change lock type"
4598 };
4599 static const true_false_string tfs_lock_type_oplock = {
4600         "This is an oplock break notification/response",
4601         "This is not an oplock break notification/response"
4602 };
4603 static const true_false_string tfs_lock_type_shared = {
4604         "This is a shared lock",
4605         "This is an exclusive lock"
4606 };
4607 static int
4608 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4609 {
4610         guint8  wc, cmd=0xff, lt=0;
4611         guint16 andxoffset=0, un=0, ln=0, bc, fid;
4612         guint32 to;
4613         proto_item *litem = NULL;
4614         proto_tree *ltree = NULL;
4615         proto_item *it = NULL;
4616         proto_tree *tr = NULL;
4617         int old_offset = offset;
4618
4619         WORD_COUNT;
4620
4621         /* next smb command */
4622         cmd = tvb_get_guint8(tvb, offset);
4623         if(cmd!=0xff){
4624                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4625         } else {
4626                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4627         }
4628         offset += 1;
4629
4630         /* reserved byte */
4631         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4632         offset += 1;
4633
4634         /* andxoffset */
4635         andxoffset = tvb_get_letohs(tvb, offset);
4636         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4637         offset += 2;
4638
4639         /* fid */
4640         fid = tvb_get_letohs(tvb, offset);
4641         add_fid(tvb, pinfo, tree, offset, 2, fid);
4642         offset += 2;
4643
4644         /* lock type */
4645         lt = tvb_get_guint8(tvb, offset);
4646         if(tree){
4647                 litem = proto_tree_add_text(tree, tvb, offset, 1,
4648                         "Lock Type: 0x%02x", lt);
4649                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
4650         }
4651         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
4652                 tvb, offset, 1, lt);
4653         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
4654                 tvb, offset, 1, lt);
4655         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
4656                 tvb, offset, 1, lt);
4657         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
4658                 tvb, offset, 1, lt);
4659         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
4660                 tvb, offset, 1, lt);
4661         offset += 1;
4662
4663         /* oplock level */
4664         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
4665         offset += 1;
4666
4667         /* timeout */
4668         to = tvb_get_letohl(tvb, offset);
4669         if (to == 0)
4670                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
4671         else if (to == 0xffffffff)
4672                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
4673         else
4674                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4675         offset += 4;
4676
4677         /* number of unlocks */
4678         un = tvb_get_letohs(tvb, offset);
4679         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
4680         offset += 2;
4681
4682         /* number of locks */
4683         ln = tvb_get_letohs(tvb, offset);
4684         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
4685         offset += 2;
4686
4687         BYTE_COUNT;
4688
4689         /* unlocks */
4690         if(un){
4691                 old_offset = offset;
4692
4693                 it = proto_tree_add_text(tree, tvb, offset, -1,
4694                         "Unlocks");
4695                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
4696                 while(un--){
4697                         proto_item *litem = NULL;
4698                         proto_tree *ltree = NULL;
4699                         if(lt&0x10){
4700                                 /* large lock format */
4701                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4702                                         "Unlock");
4703                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4704
4705                                 /* PID */
4706                                 CHECK_BYTE_COUNT(2);
4707                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4708                                 COUNT_BYTES(2);
4709
4710                                 /* 2 reserved bytes */
4711                                 CHECK_BYTE_COUNT(2);
4712                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4713                                 COUNT_BYTES(2);
4714
4715                                 /* offset */
4716                                 CHECK_BYTE_COUNT(8);
4717                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4718                                 COUNT_BYTES(8);
4719
4720                                 /* length */
4721                                 CHECK_BYTE_COUNT(8);
4722                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4723                                 COUNT_BYTES(8);
4724                         } else {
4725                                 /* normal lock format */
4726                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4727                                         "Unlock");
4728                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4729
4730                                 /* PID */
4731                                 CHECK_BYTE_COUNT(2);
4732                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4733                                 COUNT_BYTES(2);
4734
4735                                 /* offset */
4736                                 CHECK_BYTE_COUNT(4);
4737                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4738                                 COUNT_BYTES(4);
4739
4740                                 /* lock count */
4741                                 CHECK_BYTE_COUNT(4);
4742                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4743                                 COUNT_BYTES(4);
4744                         }
4745                 }
4746                 proto_item_set_len(it, offset-old_offset);
4747                 it = NULL;
4748         }
4749
4750         /* locks */
4751         if(ln){
4752                 old_offset = offset;
4753
4754                 it = proto_tree_add_text(tree, tvb, offset, -1,
4755                         "Locks");
4756                 tr = proto_item_add_subtree(it, ett_smb_locks);
4757                 while(ln--){
4758                         proto_item *litem = NULL;
4759                         proto_tree *ltree = NULL;
4760                         if(lt&0x10){
4761                                 /* large lock format */
4762                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4763                                         "Lock");
4764                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
4765
4766                                 /* PID */
4767                                 CHECK_BYTE_COUNT(2);
4768                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4769                                 COUNT_BYTES(2);
4770
4771                                 /* 2 reserved bytes */
4772                                 CHECK_BYTE_COUNT(2);
4773                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4774                                 COUNT_BYTES(2);
4775
4776                                 /* offset */
4777                                 CHECK_BYTE_COUNT(8);
4778                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4779                                 COUNT_BYTES(8);
4780
4781                                 /* length */
4782                                 CHECK_BYTE_COUNT(8);
4783                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4784                                 COUNT_BYTES(8);
4785                         } else {
4786                                 /* normal lock format */
4787                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4788                                         "Unlock");
4789                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4790
4791                                 /* PID */
4792                                 CHECK_BYTE_COUNT(2);
4793                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4794                                 COUNT_BYTES(2);
4795
4796                                 /* offset */
4797                                 CHECK_BYTE_COUNT(4);
4798                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4799                                 COUNT_BYTES(4);
4800
4801                                 /* lock count */
4802                                 CHECK_BYTE_COUNT(4);
4803                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4804                                 COUNT_BYTES(4);
4805                         }
4806                 }
4807                 proto_item_set_len(it, offset-old_offset);
4808                 it = NULL;
4809         }
4810
4811         END_OF_SMB
4812
4813         if (it != NULL) {
4814                 /*
4815                  * We ran out of byte count in the middle of dissecting
4816                  * the locks or the unlocks; set the site of the item
4817                  * we were dissecting.
4818                  */
4819                 proto_item_set_len(it, offset-old_offset);
4820         }
4821
4822         /* call AndXCommand (if there are any) */
4823         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4824
4825         return offset;
4826 }
4827
4828 static int
4829 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4830 {
4831         guint8  wc, cmd=0xff;
4832         guint16 andxoffset=0;
4833         guint16 bc;
4834
4835         WORD_COUNT;
4836
4837         /* next smb command */
4838         cmd = tvb_get_guint8(tvb, offset);
4839         if(cmd!=0xff){
4840                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4841         } else {
4842                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4843         }
4844         offset += 1;
4845
4846         /* reserved byte */
4847         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4848         offset += 1;
4849
4850         /* andxoffset */
4851         andxoffset = tvb_get_letohs(tvb, offset);
4852         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4853         offset += 2;
4854
4855         BYTE_COUNT;
4856
4857         END_OF_SMB
4858
4859         /* call AndXCommand (if there are any) */
4860         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4861
4862         return offset;
4863 }
4864
4865
4866 static const value_string oa_open_vals[] = {
4867         { 0,            "No action taken?"},
4868         { 1,            "The file existed and was opened"},
4869         { 2,            "The file did not exist but was created"},
4870         { 3,            "The file existed and was truncated"},
4871         {0,     NULL}
4872 };
4873 static const true_false_string tfs_oa_lock = {
4874         "File is currently opened only by this user",
4875         "File is opened by another user (or mode not supported by server)"
4876 };
4877 static int
4878 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
4879 {
4880         guint16 mask;
4881         proto_item *item = NULL;
4882         proto_tree *tree = NULL;
4883
4884         mask = tvb_get_letohs(tvb, offset);
4885
4886         if(parent_tree){
4887                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4888                         "Action: 0x%04x", mask);
4889                 tree = proto_item_add_subtree(item, ett_smb_open_action);
4890         }
4891
4892         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
4893                 tvb, offset, 2, mask);
4894         proto_tree_add_uint(tree, hf_smb_open_action_open,
4895                 tvb, offset, 2, mask);
4896
4897         offset += 2;
4898
4899         return offset;
4900 }
4901
4902 static const true_false_string tfs_open_flags_add_info = {
4903         "Additional information requested",
4904         "Additional information not requested"
4905 };
4906 static const true_false_string tfs_open_flags_ex_oplock = {
4907         "Exclusive oplock requested",
4908         "Exclusive oplock not requested"
4909 };
4910 static const true_false_string tfs_open_flags_batch_oplock = {
4911         "Batch oplock requested",
4912         "Batch oplock not requested"
4913 };
4914 static const true_false_string tfs_open_flags_ealen = {
4915         "Total length of EAs requested",
4916         "Total length of EAs not requested"
4917 };
4918 static int
4919 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4920 {
4921         guint16 mask;
4922         proto_item *item = NULL;
4923         proto_tree *tree = NULL;
4924
4925         mask = tvb_get_letohs(tvb, offset);
4926
4927         if(parent_tree){
4928                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4929                         "Flags: 0x%04x", mask);
4930                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
4931         }
4932
4933         if(bm&0x0001){
4934                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
4935                         tvb, offset, 2, mask);
4936         }
4937         if(bm&0x0002){
4938                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
4939                         tvb, offset, 2, mask);
4940         }
4941         if(bm&0x0004){
4942                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
4943                         tvb, offset, 2, mask);
4944         }
4945         if(bm&0x0008){
4946                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
4947                         tvb, offset, 2, mask);
4948         }
4949
4950         offset += 2;
4951
4952         return offset;
4953 }
4954
4955 static const value_string filetype_vals[] = {
4956         { 0,            "Disk file or directory"},
4957         { 1,            "Named pipe in byte mode"},
4958         { 2,            "Named pipe in message mode"},
4959         { 3,            "Spooled printer"},
4960         {0, NULL}
4961 };
4962 static int
4963 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4964 {
4965         guint8  wc, cmd=0xff;
4966         guint16 andxoffset=0, bc;
4967         smb_info_t *si = pinfo->private_data;
4968         int fn_len;
4969         const char *fn;
4970
4971         WORD_COUNT;
4972
4973         /* next smb command */
4974         cmd = tvb_get_guint8(tvb, offset);
4975         if(cmd!=0xff){
4976                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4977         } else {
4978                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4979         }
4980         offset += 1;
4981
4982         /* reserved byte */
4983         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4984         offset += 1;
4985
4986         /* andxoffset */
4987         andxoffset = tvb_get_letohs(tvb, offset);
4988         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4989         offset += 2;
4990
4991         /* open flags */
4992         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
4993
4994         /* desired access */
4995         offset = dissect_access(tvb, tree, offset, "Desired");
4996
4997         /* Search Attributes */
4998         offset = dissect_search_attributes(tvb, tree, offset);
4999
5000         /* File Attributes */
5001         offset = dissect_file_attributes(tvb, tree, offset, 2);
5002
5003         /* creation time */
5004         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
5005
5006         /* open function */
5007         offset = dissect_open_function(tvb, tree, offset);
5008
5009         /* allocation size */
5010         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
5011         offset += 4;
5012
5013         /* 8 reserved bytes */
5014         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
5015         offset += 8;
5016
5017         BYTE_COUNT;
5018
5019         /* file name */
5020         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5021                 FALSE, FALSE, &bc);
5022         if (fn == NULL)
5023                 goto endofcommand;
5024         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5025                 fn);
5026         COUNT_BYTES(fn_len);
5027
5028         if (check_col(pinfo->cinfo, COL_INFO)) {
5029                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
5030         }
5031
5032         END_OF_SMB
5033
5034         /* call AndXCommand (if there are any) */
5035         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5036
5037         return offset;
5038 }
5039
5040 static const true_false_string tfs_ipc_state_nonblocking = {
5041         "Reads/writes return immediately if no data available",
5042         "Reads/writes block if no data available"
5043 };
5044 static const value_string ipc_state_endpoint_vals[] = {
5045         { 0,            "Consumer end of pipe"},
5046         { 1,            "Server end of pipe"},
5047         {0,     NULL}
5048 };
5049 static const value_string ipc_state_pipe_type_vals[] = {
5050         { 0,            "Byte stream pipe"},
5051         { 1,            "Message pipe"},
5052         {0,     NULL}
5053 };
5054 static const value_string ipc_state_read_mode_vals[] = {
5055         { 0,            "Read pipe as a byte stream"},
5056         { 1,            "Read messages from pipe"},
5057         {0,     NULL}
5058 };
5059
5060 int
5061 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
5062     gboolean setstate)
5063 {
5064         guint16 mask;
5065         proto_item *item = NULL;
5066         proto_tree *tree = NULL;
5067
5068         mask = tvb_get_letohs(tvb, offset);
5069
5070         if(parent_tree){
5071                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5072                         "IPC State: 0x%04x", mask);
5073                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
5074         }
5075
5076         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
5077                 tvb, offset, 2, mask);
5078         if (!setstate) {
5079                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
5080                         tvb, offset, 2, mask);
5081                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
5082                         tvb, offset, 2, mask);
5083         }
5084         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
5085                 tvb, offset, 2, mask);
5086         if (!setstate) {
5087                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
5088                         tvb, offset, 2, mask);
5089         }
5090
5091         offset += 2;
5092
5093         return offset;
5094 }
5095
5096 static int
5097 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5098 {
5099         guint8  wc, cmd=0xff;
5100         guint16 andxoffset=0, bc;
5101         guint16 fid;
5102
5103         WORD_COUNT;
5104
5105         /* next smb command */
5106         cmd = tvb_get_guint8(tvb, offset);
5107         if(cmd!=0xff){
5108                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5109         } else {
5110                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5111         }
5112         offset += 1;
5113
5114         /* reserved byte */
5115         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5116         offset += 1;
5117
5118         /* andxoffset */
5119         andxoffset = tvb_get_letohs(tvb, offset);
5120         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5121         offset += 2;
5122
5123         /* fid */
5124         fid = tvb_get_letohs(tvb, offset);
5125         add_fid(tvb, pinfo, tree, offset, 2, fid);
5126         offset += 2;
5127
5128         /* File Attributes */
5129         offset = dissect_file_attributes(tvb, tree, offset, 2);
5130
5131         /* last write time */
5132         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
5133
5134         /* File Size */
5135         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5136         offset += 4;
5137
5138         /* granted access */
5139         offset = dissect_access(tvb, tree, offset, "Granted");
5140
5141         /* File Type */
5142         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
5143         offset += 2;
5144
5145         /* IPC State */
5146         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
5147
5148         /* open_action */
5149         offset = dissect_open_action(tvb, tree, offset);
5150
5151         /* server fid */
5152         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
5153         offset += 4;
5154
5155         /* 2 reserved bytes */
5156         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5157         offset += 2;
5158
5159         BYTE_COUNT;
5160
5161         END_OF_SMB
5162
5163         /* call AndXCommand (if there are any) */
5164         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5165
5166         return offset;
5167 }
5168
5169 static int
5170 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5171 {
5172         guint8  wc, cmd=0xff;
5173         guint16 andxoffset=0, bc, maxcnt = 0;
5174         guint32 ofs = 0;
5175         smb_info_t *si;
5176         unsigned int fid;
5177
5178         WORD_COUNT;
5179
5180         /* next smb command */
5181         cmd = tvb_get_guint8(tvb, offset);
5182         if(cmd!=0xff){
5183                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5184         } else {
5185                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5186         }
5187         offset += 1;
5188
5189         /* reserved byte */
5190         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5191         offset += 1;
5192
5193         /* andxoffset */
5194         andxoffset = tvb_get_letohs(tvb, offset);
5195         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5196         offset += 2;
5197
5198         /* fid */
5199         fid = tvb_get_letohs(tvb, offset);
5200         add_fid(tvb, pinfo, tree, offset, 2, fid);
5201         offset += 2;
5202         if (!pinfo->fd->flags.visited) {
5203                 /* remember the FID for the processing of the response */
5204                 si = (smb_info_t *)pinfo->private_data;
5205                 si->sip->extra_info=(void *)fid;
5206         }
5207
5208         /* offset */
5209         ofs = tvb_get_letohl(tvb, offset);
5210         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5211         offset += 4;
5212
5213         /* max count */
5214         maxcnt = tvb_get_letohs(tvb, offset);
5215         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
5216         offset += 2;
5217
5218         if (check_col(pinfo->cinfo, COL_INFO))
5219                 col_append_fstr(pinfo->cinfo, COL_INFO,
5220                                 ", %u byte%s at offset %u", maxcnt,
5221                                 (maxcnt == 1) ? "" : "s", ofs);
5222
5223         /* min count */
5224         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
5225         offset += 2;
5226
5227         /* XXX - max count high */
5228         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5229         offset += 4;
5230
5231         /* remaining */
5232         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5233         offset += 2;
5234
5235         if(wc==12){
5236                 /* high offset */
5237                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5238                 offset += 4;
5239         }
5240
5241         BYTE_COUNT;
5242
5243         END_OF_SMB
5244
5245         /* call AndXCommand (if there are any) */
5246         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5247
5248         return offset;
5249 }
5250
5251 static int
5252 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5253 {
5254         guint8  wc, cmd=0xff;
5255         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
5256         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5257         int fid=0;
5258
5259         WORD_COUNT;
5260
5261         /* next smb command */
5262         cmd = tvb_get_guint8(tvb, offset);
5263         if(cmd!=0xff){
5264                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5265         } else {
5266                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5267         }
5268         offset += 1;
5269
5270         /* reserved byte */
5271         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5272         offset += 1;
5273
5274         /* andxoffset */
5275         andxoffset = tvb_get_letohs(tvb, offset);
5276         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5277         offset += 2;
5278
5279         /* If we have seen the request, then print which FID this refers to */
5280         /* first check if we have seen the request */
5281         if(si->sip != NULL && si->sip->frame_req>0){
5282                 fid=(int)si->sip->extra_info;
5283                 add_fid(tvb, pinfo, tree, 0, 0, fid);
5284         }
5285
5286         /* remaining */
5287         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5288         offset += 2;
5289
5290         /* data compaction mode */
5291         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
5292         offset += 2;
5293
5294         /* 2 reserved bytes */
5295         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5296         offset += 2;
5297
5298         /* data len */
5299         datalen = tvb_get_letohs(tvb, offset);
5300         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5301         offset += 2;
5302
5303         if (check_col(pinfo->cinfo, COL_INFO))
5304                 col_append_fstr(pinfo->cinfo, COL_INFO,
5305                                 ", %u byte%s", datalen,
5306                                 (datalen == 1) ? "" : "s");
5307
5308         /* data offset */
5309         dataoffset=tvb_get_letohs(tvb, offset);
5310         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5311         offset += 2;
5312
5313         /* 10 reserved bytes */
5314         /* XXX - first 2 bytes are data length high, not reserved */
5315         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
5316         offset += 10;
5317
5318         BYTE_COUNT;
5319
5320         /* file data, might be DCERPC on a pipe */
5321         if(bc){
5322                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5323                     top_tree, offset, bc, datalen, 0, fid);
5324                 bc = 0;
5325         }
5326
5327         END_OF_SMB
5328
5329         /* call AndXCommand (if there are any) */
5330         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5331
5332         return offset;
5333 }
5334
5335 static int
5336 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5337 {
5338         guint32 ofs=0;
5339         guint8  wc, cmd=0xff;
5340         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
5341         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5342         unsigned int fid=0;
5343         guint16 mode = 0;
5344
5345
5346         WORD_COUNT;
5347
5348         /* next smb command */
5349         cmd = tvb_get_guint8(tvb, offset);
5350         if(cmd!=0xff){
5351                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5352         } else {
5353                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5354         }
5355         offset += 1;
5356
5357         /* reserved byte */
5358         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5359         offset += 1;
5360
5361         /* andxoffset */
5362         andxoffset = tvb_get_letohs(tvb, offset);
5363         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5364         offset += 2;
5365
5366         /* fid */
5367         fid = tvb_get_letohs(tvb, offset);
5368         add_fid(tvb, pinfo, tree, offset, 2, fid);
5369         offset += 2;
5370         if (!pinfo->fd->flags.visited) {
5371                 /* remember the FID for the processing of the response */
5372                 si->sip->extra_info=(void *)fid;
5373         }
5374
5375         /* offset */
5376         ofs = tvb_get_letohl(tvb, offset);
5377         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5378         offset += 4;
5379
5380         /* reserved */
5381         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5382         offset += 4;
5383
5384         /* mode */
5385         mode = tvb_get_letohs(tvb, offset);
5386         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
5387
5388         /* remaining */
5389         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5390         offset += 2;
5391
5392         /* XXX - data length high */
5393         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5394         offset += 2;
5395
5396         /* data len */
5397         datalen = tvb_get_letohs(tvb, offset);
5398         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5399         offset += 2;
5400
5401         /* data offset */
5402         dataoffset=tvb_get_letohs(tvb, offset);
5403         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5404         offset += 2;
5405
5406         /* FIXME: handle Large (48-bit) byte/offset to COL_INFO */
5407         if (check_col(pinfo->cinfo, COL_INFO))
5408                 col_append_fstr(pinfo->cinfo, COL_INFO,
5409                                 ", %u byte%s at offset %u", datalen,
5410                                 (datalen == 1) ? "" : "s", ofs);
5411
5412         if(wc==14){
5413                 /* high offset */
5414                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5415                 offset += 4;
5416         }
5417
5418         BYTE_COUNT;
5419
5420         /* if both the MessageStart and the  WriteRawNamedPipe flags are set
5421            the first two bytes of the payload is the length of the data
5422            also this tells us that this is indeed the IPC$ share
5423            (if we didnt already know that 
5424         */
5425         if((mode&(WRITE_MODE_MESSAGE_START|WRITE_MODE_RAW))==(WRITE_MODE_MESSAGE_START|WRITE_MODE_RAW)){
5426                 proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, TRUE);
5427                 offset += 2;
5428                 dataoffset += 2;
5429                 bc -= 2;
5430                 datalen -= 2;
5431                 if(si->sip){
5432                         si->sip->flags|=SMB_SIF_TID_IS_IPC;
5433                 }
5434         }
5435
5436         /* file data, might be DCERPC on a pipe */
5437         if (bc != 0) {
5438                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5439                     top_tree, offset, bc, datalen, 0, fid);
5440                 bc = 0;
5441         }
5442
5443         END_OF_SMB
5444
5445         /* call AndXCommand (if there are any) */
5446         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5447
5448         return offset;
5449 }
5450
5451 static int
5452 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5453 {
5454         guint8  wc, cmd=0xff;
5455         guint16 andxoffset=0, bc, datalen=0;
5456         smb_info_t *si;
5457
5458         WORD_COUNT;
5459
5460         /* next smb command */
5461         cmd = tvb_get_guint8(tvb, offset);
5462         if(cmd!=0xff){
5463                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5464         } else {
5465                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5466         }
5467         offset += 1;
5468
5469         /* reserved byte */
5470         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5471         offset += 1;
5472
5473         /* andxoffset */
5474         andxoffset = tvb_get_letohs(tvb, offset);
5475         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5476         offset += 2;
5477
5478         /* If we have seen the request, then print which FID this refers to */
5479         si = (smb_info_t *)pinfo->private_data;
5480         /* first check if we have seen the request */
5481         if(si->sip != NULL && si->sip->frame_req>0){
5482                 add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
5483         }
5484
5485         /* write count */
5486         datalen = tvb_get_letohs(tvb, offset);
5487         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
5488         offset += 2;
5489
5490         if (check_col(pinfo->cinfo, COL_INFO))
5491                 col_append_fstr(pinfo->cinfo, COL_INFO,
5492                                 ", %u byte%s", datalen,
5493                                 (datalen == 1) ? "" : "s");
5494
5495         /* remaining */
5496         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5497         offset += 2;
5498
5499         /* 4 reserved bytes */
5500         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5501         offset += 4;
5502
5503         BYTE_COUNT;
5504
5505         END_OF_SMB
5506
5507         /* call AndXCommand (if there are any) */
5508         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5509
5510         return offset;
5511 }
5512
5513
5514 static const true_false_string tfs_setup_action_guest = {
5515         "Logged in as GUEST",
5516         "Not logged in as GUEST"
5517 };
5518 static int
5519 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5520 {
5521         guint16 mask;
5522         proto_item *item = NULL;
5523         proto_tree *tree = NULL;
5524
5525         mask = tvb_get_letohs(tvb, offset);
5526
5527         if(parent_tree){
5528                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5529                         "Action: 0x%04x", mask);
5530                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
5531         }
5532
5533         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
5534                 tvb, offset, 2, mask);
5535
5536         offset += 2;
5537
5538         return offset;
5539 }
5540
5541
5542 static int
5543 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5544 {
5545         guint8  wc, cmd=0xff;
5546         guint16 bc;
5547         guint16 andxoffset=0;
5548         smb_info_t *si = pinfo->private_data;
5549         int an_len;
5550         const char *an;
5551         int dn_len;
5552         const char *dn;
5553         guint16 pwlen=0;
5554         guint16 sbloblen=0;
5555         guint16 apwlen=0, upwlen=0;
5556
5557         WORD_COUNT;
5558
5559         /* next smb command */
5560         cmd = tvb_get_guint8(tvb, offset);
5561         if(cmd!=0xff){
5562                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5563         } else {
5564                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5565         }
5566         offset += 1;
5567
5568         /* reserved byte */
5569         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5570         offset += 1;
5571
5572         /* andxoffset */
5573         andxoffset = tvb_get_letohs(tvb, offset);
5574         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5575         offset += 2;
5576
5577         /* Maximum Buffer Size */
5578         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
5579         offset += 2;
5580
5581         /* Maximum Multiplex Count */
5582         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
5583         offset += 2;
5584
5585         /* VC Number */
5586         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
5587         offset += 2;
5588
5589         /* session key */
5590         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
5591         offset += 4;
5592
5593         switch (wc) {
5594         case 10:
5595                 /* password length, ASCII*/
5596                 pwlen = tvb_get_letohs(tvb, offset);
5597                 proto_tree_add_uint(tree, hf_smb_password_len,
5598                         tvb, offset, 2, pwlen);
5599                 offset += 2;
5600
5601                 /* 4 reserved bytes */
5602                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5603                 offset += 4;
5604
5605                 break;
5606
5607         case 12:
5608                 /* security blob length */
5609                 sbloblen = tvb_get_letohs(tvb, offset);
5610                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5611                 offset += 2;
5612
5613                 /* 4 reserved bytes */
5614                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5615                 offset += 4;
5616
5617                 /* capabilities */
5618                 dissect_negprot_capabilities(tvb, tree, offset);
5619                 offset += 4;
5620
5621                 break;
5622
5623         case 13:
5624                 /* password length, ANSI*/
5625                 apwlen = tvb_get_letohs(tvb, offset);
5626                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
5627                         tvb, offset, 2, apwlen);
5628                 offset += 2;
5629
5630                 /* password length, Unicode*/
5631                 upwlen = tvb_get_letohs(tvb, offset);
5632                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
5633                         tvb, offset, 2, upwlen);
5634                 offset += 2;
5635
5636                 /* 4 reserved bytes */
5637                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5638                 offset += 4;
5639
5640                 /* capabilities */
5641                 dissect_negprot_capabilities(tvb, tree, offset);
5642                 offset += 4;
5643
5644                 break;
5645         }
5646
5647         BYTE_COUNT;
5648
5649         if (wc==12) {
5650                 proto_item *blob_item;
5651
5652                 /* security blob */
5653
5654                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
5655                                                 tvb, offset, sbloblen, TRUE);
5656
5657                 /* As an optimization, because Windows is perverse,
5658                    we check to see if NTLMSSP is the first part of the 
5659                    blob, and if so, call the NTLMSSP dissector,
5660                    otherwise we call the GSS-API dissector. This is because
5661                    Windows can request RAW NTLMSSP, but will happily handle
5662                    a client that wraps NTLMSSP in SPNEGO
5663                 */
5664
5665                 if(sbloblen){
5666                         tvbuff_t *blob_tvb;
5667                         proto_tree *blob_tree;
5668
5669                         blob_tree = proto_item_add_subtree(blob_item, 
5670                                                            ett_smb_secblob);
5671                         CHECK_BYTE_COUNT(sbloblen);
5672
5673                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
5674                                                   sbloblen);
5675
5676                         if (si && si->ct && si->ct->raw_ntlmssp && 
5677                             !strncmp("NTLMSSP", 
5678                                      tvb_get_ptr(tvb, offset, 7), 7)) {
5679                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
5680                                          blob_tree);
5681
5682                         }
5683                         else {
5684                           call_dissector(gssapi_handle, blob_tvb, 
5685                                          pinfo, blob_tree);
5686                         }
5687
5688                         COUNT_BYTES(sbloblen);
5689                 }
5690
5691                 /* OS */
5692                 an = get_unicode_or_ascii_string(tvb, &offset,
5693                         si->unicode, &an_len, FALSE, FALSE, &bc);
5694                 if (an == NULL)
5695                         goto endofcommand;
5696                 proto_tree_add_string(tree, hf_smb_os, tvb,
5697                         offset, an_len, an);
5698                 COUNT_BYTES(an_len);
5699
5700                 /* LANMAN */
5701                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5702                  * padding/null string/whatever in front of this. W2K doesn't
5703                  * appear to. I suspect that's a bug that got fixed; I also
5704                  * suspect that, in practice, nobody ever looks at that field
5705                  * because the bug didn't appear to get fixed until NT 5.0....
5706                  */
5707                 an = get_unicode_or_ascii_string(tvb, &offset,
5708                         si->unicode, &an_len, FALSE, FALSE, &bc);
5709                 if (an == NULL)
5710                         goto endofcommand;
5711                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5712                         offset, an_len, an);
5713                 COUNT_BYTES(an_len);
5714
5715                 /* Primary domain */
5716                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5717                  * byte in front of this, at least if all the strings are
5718                  * ASCII and the account name is empty. Another bug?
5719                  */
5720                 dn = get_unicode_or_ascii_string(tvb, &offset,
5721                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5722                 if (dn == NULL)
5723                         goto endofcommand;
5724                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5725                         offset, dn_len, dn);
5726                 COUNT_BYTES(dn_len);
5727         } else {
5728                 switch (wc) {
5729
5730                 case 10:
5731                         if(pwlen){
5732                                 /* password, ASCII */
5733                                 CHECK_BYTE_COUNT(pwlen);
5734                                 proto_tree_add_item(tree, hf_smb_password,
5735                                         tvb, offset, pwlen, TRUE);
5736                                 COUNT_BYTES(pwlen);
5737                         }
5738
5739                         break;
5740
5741                 case 13:
5742                         if(apwlen){
5743                                 /* password, ANSI */
5744                                 CHECK_BYTE_COUNT(apwlen);
5745                                 proto_tree_add_item(tree, hf_smb_ansi_password,
5746                                         tvb, offset, apwlen, TRUE);
5747                                 COUNT_BYTES(apwlen);
5748                         }
5749
5750                         if(upwlen){
5751                                 /* password, Unicode */
5752                                 CHECK_BYTE_COUNT(upwlen);
5753                                 proto_tree_add_item(tree, hf_smb_unicode_password,
5754                                         tvb, offset, upwlen, TRUE);
5755                                 COUNT_BYTES(upwlen);
5756                         }
5757
5758                         break;
5759                 }
5760
5761                 /* Account Name */
5762                 an = get_unicode_or_ascii_string(tvb, &offset,
5763                         si->unicode, &an_len, FALSE, FALSE, &bc);
5764                 if (an == NULL)
5765                         goto endofcommand;
5766                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
5767                         an);
5768                 COUNT_BYTES(an_len);
5769
5770                 /* Primary domain */
5771                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5772                  * byte in front of this, at least if all the strings are
5773                  * ASCII and the account name is empty. Another bug?
5774                  */
5775                 dn = get_unicode_or_ascii_string(tvb, &offset,
5776                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5777                 if (dn == NULL)
5778                         goto endofcommand;
5779                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5780                         offset, dn_len, dn);
5781                 COUNT_BYTES(dn_len);
5782
5783                 if (check_col(pinfo->cinfo, COL_INFO)) {
5784                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
5785
5786                         if (!dn[0] && !an[0])
5787                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5788                                                 "anonymous");
5789                         else
5790                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5791                                                 "%s\\%s", dn,an);
5792                 }
5793
5794                 /* OS */
5795                 an = get_unicode_or_ascii_string(tvb, &offset,
5796                         si->unicode, &an_len, FALSE, FALSE, &bc);
5797                 if (an == NULL)
5798                         goto endofcommand;
5799                 proto_tree_add_string(tree, hf_smb_os, tvb,
5800                         offset, an_len, an);
5801                 COUNT_BYTES(an_len);
5802
5803                 /* LANMAN */
5804                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5805                  * padding/null string/whatever in front of this. W2K doesn't
5806                  * appear to. I suspect that's a bug that got fixed; I also
5807                  * suspect that, in practice, nobody ever looks at that field
5808                  * because the bug didn't appear to get fixed until NT 5.0....
5809                  */
5810                 an = get_unicode_or_ascii_string(tvb, &offset,
5811                         si->unicode, &an_len, FALSE, FALSE, &bc);
5812                 if (an == NULL)
5813                         goto endofcommand;
5814                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5815                         offset, an_len, an);
5816                 COUNT_BYTES(an_len);
5817         }
5818
5819         END_OF_SMB
5820
5821         /* call AndXCommand (if there are any) */
5822         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5823
5824         return offset;
5825 }
5826
5827 static int
5828 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5829 {
5830         guint8  wc, cmd=0xff;
5831         guint16 andxoffset=0, bc;
5832         guint16 sbloblen=0;
5833         smb_info_t *si = pinfo->private_data;
5834         int an_len;
5835         const char *an;
5836
5837         WORD_COUNT;
5838
5839         /* next smb command */
5840         cmd = tvb_get_guint8(tvb, offset);
5841         if(cmd!=0xff){
5842                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5843         } else {
5844                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5845         }
5846         offset += 1;
5847
5848         /* reserved byte */
5849         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5850         offset += 1;
5851
5852         /* andxoffset */
5853         andxoffset = tvb_get_letohs(tvb, offset);
5854         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5855         offset += 2;
5856
5857         /* flags */
5858         offset = dissect_setup_action(tvb, tree, offset);
5859
5860         if(wc==4){
5861                 /* security blob length */
5862                 sbloblen = tvb_get_letohs(tvb, offset);
5863                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5864                 offset += 2;
5865         }
5866
5867         BYTE_COUNT;
5868
5869         if(wc==4) {
5870                 proto_item *blob_item;
5871
5872                 /* security blob */
5873
5874                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
5875                                                 tvb, offset, sbloblen, TRUE);
5876
5877                 if(sbloblen){
5878                         tvbuff_t *blob_tvb;
5879                         proto_tree *blob_tree;
5880
5881                         blob_tree = proto_item_add_subtree(blob_item, 
5882                                                            ett_smb_secblob);
5883                         CHECK_BYTE_COUNT(sbloblen);
5884
5885                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
5886                                                     sbloblen);
5887
5888                         if (si && si->ct && si->ct->raw_ntlmssp && 
5889                             !strncmp("NTLMSSP", 
5890                                      tvb_get_ptr(tvb, offset, 7), 7)) {
5891                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
5892                                          blob_tree);
5893
5894                         }
5895                         else {
5896                           call_dissector(gssapi_handle, blob_tvb, pinfo, 
5897                                          blob_tree);
5898
5899                         }
5900
5901                         COUNT_BYTES(sbloblen);
5902                 }
5903         }
5904
5905         /* OS */
5906         an = get_unicode_or_ascii_string(tvb, &offset,
5907                 si->unicode, &an_len, FALSE, FALSE, &bc);
5908         if (an == NULL)
5909                 goto endofcommand;
5910         proto_tree_add_string(tree, hf_smb_os, tvb,
5911                 offset, an_len, an);
5912         COUNT_BYTES(an_len);
5913
5914         /* LANMAN */
5915         an = get_unicode_or_ascii_string(tvb, &offset,
5916                 si->unicode, &an_len, FALSE, FALSE, &bc);
5917         if (an == NULL)
5918                 goto endofcommand;
5919         proto_tree_add_string(tree, hf_smb_lanman, tvb,
5920                 offset, an_len, an);
5921         COUNT_BYTES(an_len);
5922
5923         if(wc==3) {
5924                 /* Primary domain */
5925                 an = get_unicode_or_ascii_string(tvb, &offset,
5926                         si->unicode, &an_len, FALSE, FALSE, &bc);
5927                 if (an == NULL)
5928                         goto endofcommand;
5929                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5930                         offset, an_len, an);
5931                 COUNT_BYTES(an_len);
5932         }
5933
5934         END_OF_SMB
5935
5936         /* call AndXCommand (if there are any) */
5937         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5938
5939         return offset;
5940 }
5941
5942
5943 static int
5944 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5945 {
5946         guint8  wc, cmd=0xff;
5947         guint16 andxoffset=0;
5948         guint16 bc;
5949
5950         WORD_COUNT;
5951
5952         /* next smb command */
5953         cmd = tvb_get_guint8(tvb, offset);
5954         if(cmd!=0xff){
5955                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5956         } else {
5957                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5958         }
5959         offset += 1;
5960
5961         /* reserved byte */
5962         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5963         offset += 1;
5964
5965         /* andxoffset */
5966         andxoffset = tvb_get_letohs(tvb, offset);
5967         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5968         offset += 2;
5969
5970         BYTE_COUNT;
5971
5972         END_OF_SMB
5973
5974         /* call AndXCommand (if there are any) */
5975         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5976
5977         return offset;
5978 }
5979
5980
5981 static const true_false_string tfs_connect_support_search = {
5982         "Exclusive search bits supported",
5983         "Exclusive search bits not supported"
5984 };
5985 static const true_false_string tfs_connect_support_in_dfs = {
5986         "Share is in Dfs",
5987         "Share isn't in Dfs"
5988 };
5989
5990 static int
5991 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5992 {
5993         guint16 mask;
5994         proto_item *item = NULL;
5995         proto_tree *tree = NULL;
5996
5997         mask = tvb_get_letohs(tvb, offset);
5998
5999         if(parent_tree){
6000                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6001                         "Optional Support: 0x%04x", mask);
6002                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
6003         }
6004
6005         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
6006                 tvb, offset, 2, mask);
6007         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
6008                 tvb, offset, 2, mask);
6009
6010         offset += 2;
6011
6012         return offset;
6013 }
6014
6015 static const true_false_string tfs_disconnect_tid = {
6016         "DISCONNECT TID",
6017         "Do NOT disconnect TID"
6018 };
6019
6020 static int
6021 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6022 {
6023         guint16 mask;
6024         proto_item *item = NULL;
6025         proto_tree *tree = NULL;
6026
6027         mask = tvb_get_letohs(tvb, offset);
6028
6029         if(parent_tree){
6030                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6031                         "Flags: 0x%04x", mask);
6032                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
6033         }
6034
6035         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
6036                 tvb, offset, 2, mask);
6037
6038         offset += 2;
6039
6040         return offset;
6041 }
6042
6043 static int
6044 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6045 {
6046         guint8  wc, cmd=0xff;
6047         guint16 bc;
6048         guint16 andxoffset=0, pwlen=0;
6049         smb_info_t *si = pinfo->private_data;
6050         int an_len;
6051         const char *an;
6052
6053         WORD_COUNT;
6054
6055         /* next smb command */
6056         cmd = tvb_get_guint8(tvb, offset);
6057         if(cmd!=0xff){
6058                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6059         } else {
6060                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
6061         }
6062         offset += 1;
6063
6064         /* reserved byte */
6065         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6066         offset += 1;
6067
6068         /* andxoffset */
6069         andxoffset = tvb_get_letohs(tvb, offset);
6070         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6071         offset += 2;
6072
6073         /* flags */
6074         offset = dissect_connect_flags(tvb, tree, offset);
6075
6076         /* password length*/
6077         pwlen = tvb_get_letohs(tvb, offset);
6078         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
6079         offset += 2;
6080
6081         BYTE_COUNT;
6082
6083         /* password */
6084         CHECK_BYTE_COUNT(pwlen);
6085         proto_tree_add_item(tree, hf_smb_password,
6086                 tvb, offset, pwlen, TRUE);
6087         COUNT_BYTES(pwlen);
6088
6089         /* Path */
6090         an = get_unicode_or_ascii_string(tvb, &offset,
6091                 si->unicode, &an_len, FALSE, FALSE, &bc);
6092         if (an == NULL)
6093                 goto endofcommand;
6094         proto_tree_add_string(tree, hf_smb_path, tvb,
6095                 offset, an_len, an);
6096         COUNT_BYTES(an_len);
6097
6098         if (check_col(pinfo->cinfo, COL_INFO)) {
6099                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
6100         }
6101
6102         /*
6103          * NOTE: the Service string is always ASCII, even if the
6104          * "strings are Unicode" bit is set in the flags2 field
6105          * of the SMB.
6106          */
6107
6108         /* Service */
6109         /* XXX - what if this runs past bc? */
6110         an_len = tvb_strsize(tvb, offset);
6111         CHECK_BYTE_COUNT(an_len);
6112         an = tvb_get_ptr(tvb, offset, an_len);
6113         proto_tree_add_string(tree, hf_smb_service, tvb,
6114                 offset, an_len, an);
6115         COUNT_BYTES(an_len);
6116
6117         END_OF_SMB
6118
6119         /* call AndXCommand (if there are any) */
6120         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6121
6122         return offset;
6123 }
6124
6125
6126 static int
6127 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6128 {
6129         guint8  wc, wleft, cmd=0xff;
6130         guint16 andxoffset=0;
6131         guint16 bc;
6132         int an_len;
6133         const char *an;
6134         smb_info_t *si = pinfo->private_data;
6135
6136         WORD_COUNT;
6137
6138         wleft = wc;     /* this is at least 1 */
6139
6140         /* next smb command */
6141         cmd = tvb_get_guint8(tvb, offset);
6142         if(cmd!=0xff){
6143                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6144         } else {
6145                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
6146         }
6147         offset += 1;
6148
6149         /* reserved byte */
6150         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6151         offset += 1;
6152
6153         wleft--;
6154         if (wleft == 0)
6155                 goto bytecount;
6156
6157         /* andxoffset */
6158         andxoffset = tvb_get_letohs(tvb, offset);
6159         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6160         offset += 2;
6161         wleft--;
6162         if (wleft == 0)
6163                 goto bytecount;
6164
6165         /* flags */
6166         offset = dissect_connect_support_bits(tvb, tree, offset);
6167         wleft--;
6168
6169         /* XXX - I've seen captures where this is 7, but I have no
6170            idea how to dissect it.  I'm guessing the third word
6171            contains connect support bits, which looks plausible
6172            from the values I've seen. */
6173
6174         while (wleft != 0) {
6175                 proto_tree_add_text(tree, tvb, offset, 2,
6176                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
6177                 offset += 2;
6178                 wleft--;
6179         }
6180
6181         BYTE_COUNT;
6182
6183         /*
6184          * NOTE: even though the SNIA CIFS spec doesn't say there's
6185          * a "Service" string if there's a word count of 2, the
6186          * document at
6187          *
6188          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
6189          *
6190          * (it's in an ugly format - text intended to be sent to a
6191          * printer, with backspaces and overstrikes used for boldfacing
6192          * and underlining; UNIX "col -b" can be used to strip the
6193          * overstrikes out) says there's a "Service" string there, and
6194          * some network traffic has it.
6195          */
6196
6197         /*
6198          * NOTE: the Service string is always ASCII, even if the
6199          * "strings are Unicode" bit is set in the flags2 field
6200          * of the SMB.
6201          */
6202
6203         /* Service */
6204         /* XXX - what if this runs past bc? */
6205         an_len = tvb_strsize(tvb, offset);
6206         CHECK_BYTE_COUNT(an_len);
6207         an = tvb_get_ptr(tvb, offset, an_len);
6208         proto_tree_add_string(tree, hf_smb_service, tvb,
6209                 offset, an_len, an);
6210         COUNT_BYTES(an_len);
6211
6212         /* Now when we know the service type, store it so that we know it for later commands down
6213            this tree */
6214         if(!pinfo->fd->flags.visited){
6215                 /* Remove any previous entry for this TID */
6216                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
6217                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
6218                 }
6219                 if(strcmp(an,"IPC") == 0){
6220                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
6221                 } else {
6222                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
6223                 }
6224         }
6225
6226
6227         if(wc==3){
6228                 if (bc != 0) {
6229                         /*
6230                          * Sometimes this isn't present.
6231                          */
6232
6233                         /* Native FS */
6234                         an = get_unicode_or_ascii_string(tvb, &offset,
6235                                 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
6236                                 &bc);
6237                         if (an == NULL)
6238                                 goto endofcommand;
6239                         proto_tree_add_string(tree, hf_smb_fs, tvb,
6240                                 offset, an_len, an);
6241                         COUNT_BYTES(an_len);
6242                 }
6243         }
6244
6245         END_OF_SMB
6246
6247         /* call AndXCommand (if there are any) */
6248         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6249
6250         return offset;
6251 }
6252
6253
6254
6255 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6256    NT Transaction command  begins here
6257    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
6258 #define NT_TRANS_CREATE         1
6259 #define NT_TRANS_IOCTL          2
6260 #define NT_TRANS_SSD            3
6261 #define NT_TRANS_NOTIFY         4
6262 #define NT_TRANS_RENAME         5
6263 #define NT_TRANS_QSD            6
6264 #define NT_TRANS_GET_USER_QUOTA 7
6265 #define NT_TRANS_SET_USER_QUOTA 8
6266 const value_string nt_cmd_vals[] = {
6267         {NT_TRANS_CREATE,               "NT CREATE"},
6268         {NT_TRANS_IOCTL,                "NT IOCTL"},
6269         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
6270         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
6271         {NT_TRANS_RENAME,               "NT RENAME"},
6272         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
6273         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
6274         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
6275         {0, NULL}
6276 };
6277
6278 static const value_string nt_ioctl_isfsctl_vals[] = {
6279         {0,     "Device IOCTL"},
6280         {1,     "FS control : FSCTL"},
6281         {0, NULL}
6282 };
6283
6284 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
6285 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
6286         "Apply the command to share root handle (MUST BE Dfs)",
6287         "Apply to this share",
6288 };
6289
6290 static const value_string nt_notify_action_vals[] = {
6291         {1,     "ADDED (object was added"},
6292         {2,     "REMOVED (object was removed)"},
6293         {3,     "MODIFIED (object was modified)"},
6294         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
6295         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
6296         {6,     "ADDED_STREAM (a stream was added)"},
6297         {7,     "REMOVED_STREAM (a stream was removed)"},
6298         {8,     "MODIFIED_STREAM (a stream was modified)"},
6299         {0, NULL}
6300 };
6301
6302 static const value_string watch_tree_vals[] = {
6303         {0,     "Current directory only"},
6304         {1,     "Subdirectories also"},
6305         {0, NULL}
6306 };
6307
6308 #define NT_NOTIFY_STREAM_WRITE  0x00000800
6309 #define NT_NOTIFY_STREAM_SIZE   0x00000400
6310 #define NT_NOTIFY_STREAM_NAME   0x00000200
6311 #define NT_NOTIFY_SECURITY      0x00000100
6312 #define NT_NOTIFY_EA            0x00000080
6313 #define NT_NOTIFY_CREATION      0x00000040
6314 #define NT_NOTIFY_LAST_ACCESS   0x00000020
6315 #define NT_NOTIFY_LAST_WRITE    0x00000010
6316 #define NT_NOTIFY_SIZE          0x00000008
6317 #define NT_NOTIFY_ATTRIBUTES    0x00000004
6318 #define NT_NOTIFY_DIR_NAME      0x00000002
6319 #define NT_NOTIFY_FILE_NAME     0x00000001
6320 static const true_false_string tfs_nt_notify_stream_write = {
6321         "Notify on changes to STREAM WRITE",
6322         "Do NOT notify on changes to stream write",
6323 };
6324 static const true_false_string tfs_nt_notify_stream_size = {
6325         "Notify on changes to STREAM SIZE",
6326         "Do NOT notify on changes to stream size",
6327 };
6328 static const true_false_string tfs_nt_notify_stream_name = {
6329         "Notify on changes to STREAM NAME",
6330         "Do NOT notify on changes to stream name",
6331 };
6332 static const true_false_string tfs_nt_notify_security = {
6333         "Notify on changes to SECURITY",
6334         "Do NOT notify on changes to security",
6335 };
6336 static const true_false_string tfs_nt_notify_ea = {
6337         "Notify on changes to EA",
6338         "Do NOT notify on changes to EA",
6339 };
6340 static const true_false_string tfs_nt_notify_creation = {
6341         "Notify on changes to CREATION TIME",
6342         "Do NOT notify on changes to creation time",
6343 };
6344 static const true_false_string tfs_nt_notify_last_access = {
6345         "Notify on changes to LAST ACCESS TIME",
6346         "Do NOT notify on changes to last access time",
6347 };
6348 static const true_false_string tfs_nt_notify_last_write = {
6349         "Notify on changes to LAST WRITE TIME",
6350         "Do NOT notify on changes to last write time",
6351 };
6352 static const true_false_string tfs_nt_notify_size = {
6353         "Notify on changes to SIZE",
6354         "Do NOT notify on changes to size",
6355 };
6356 static const true_false_string tfs_nt_notify_attributes = {
6357         "Notify on changes to ATTRIBUTES",
6358         "Do NOT notify on changes to attributes",
6359 };
6360 static const true_false_string tfs_nt_notify_dir_name = {
6361         "Notify on changes to DIR NAME",
6362         "Do NOT notify on changes to dir name",
6363 };
6364 static const true_false_string tfs_nt_notify_file_name = {
6365         "Notify on changes to FILE NAME",
6366         "Do NOT notify on changes to file name",
6367 };
6368
6369 static const value_string create_disposition_vals[] = {
6370         {0,     "Supersede (supersede existing file (if it exists))"},
6371         {1,     "Open (if file exists open it, else fail)"},
6372         {2,     "Create (if file exists fail, else create it)"},
6373         {3,     "Open If (if file exists open it, else create it)"},
6374         {4,     "Overwrite (if file exists overwrite, else fail)"},
6375         {5,     "Overwrite If (if file exists overwrite, else create it)"},
6376         {0, NULL}
6377 };
6378
6379 static const value_string impersonation_level_vals[] = {
6380         {0,     "Anonymous"},
6381         {1,     "Identification"},
6382         {2,     "Impersonation"},
6383         {3,     "Delegation"},
6384         {0, NULL}
6385 };
6386
6387 static const true_false_string tfs_nt_security_flags_context_tracking = {
6388         "Security tracking mode is DYNAMIC",
6389         "Security tracking mode is STATIC",
6390 };
6391
6392 static const true_false_string tfs_nt_security_flags_effective_only = {
6393         "ONLY ENABLED aspects of the client's security context are available",
6394         "ALL aspects of the client's security context are available",
6395 };
6396
6397 static const true_false_string tfs_nt_create_bits_oplock = {
6398         "Requesting OPLOCK",
6399         "Does NOT request oplock"
6400 };
6401
6402 static const true_false_string tfs_nt_create_bits_boplock = {
6403         "Requesting BATCH OPLOCK",
6404         "Does NOT request batch oplock"
6405 };
6406
6407 /*
6408  * XXX - must be a directory, and can be a file, or can be a directory,
6409  * and must be a file?
6410  */
6411 static const true_false_string tfs_nt_create_bits_dir = {
6412         "Target of open MUST be a DIRECTORY",
6413         "Target of open can be a file"
6414 };
6415
6416 static const true_false_string tfs_nt_access_mask_generic_read = {
6417         "GENERIC READ is set",
6418         "Generic read is NOT set"
6419 };
6420 static const true_false_string tfs_nt_access_mask_generic_write = {
6421         "GENERIC WRITE is set",
6422         "Generic write is NOT set"
6423 };
6424 static const true_false_string tfs_nt_access_mask_generic_execute = {
6425         "GENERIC EXECUTE is set",
6426         "Generic execute is NOT set"
6427 };
6428 static const true_false_string tfs_nt_access_mask_generic_all = {
6429         "GENERIC ALL is set",
6430         "Generic all is NOT set"
6431 };
6432 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
6433         "MAXIMUM ALLOWED is set",
6434         "Maximum allowed is NOT set"
6435 };
6436 static const true_false_string tfs_nt_access_mask_system_security = {
6437         "SYSTEM SECURITY is set",
6438         "System security is NOT set"
6439 };
6440 static const true_false_string tfs_nt_access_mask_synchronize = {
6441         "Can wait on handle to SYNCHRONIZE on completion of I/O",
6442         "Can NOT wait on handle to synchronize on completion of I/O"
6443 };
6444 static const true_false_string tfs_nt_access_mask_write_owner = {
6445         "Can WRITE OWNER (take ownership)",
6446         "Can NOT write owner (take ownership)"
6447 };
6448 static const true_false_string tfs_nt_access_mask_write_dac = {
6449         "OWNER may WRITE the DAC",
6450         "Owner may NOT write to the DAC"
6451 };
6452 static const true_false_string tfs_nt_access_mask_read_control = {
6453         "READ ACCESS to owner, group and ACL of the SID",
6454         "Read access is NOT granted to owner, group and ACL of the SID"
6455 };
6456 static const true_false_string tfs_nt_access_mask_delete = {
6457         "DELETE access",
6458         "NO delete access"
6459 };
6460 static const true_false_string tfs_nt_access_mask_write_attributes = {
6461         "WRITE ATTRIBUTES access",
6462         "NO write attributes access"
6463 };
6464 static const true_false_string tfs_nt_access_mask_read_attributes = {
6465         "READ ATTRIBUTES access",
6466         "NO read attributes access"
6467 };
6468 static const true_false_string tfs_nt_access_mask_delete_child = {
6469         "DELETE CHILD access",
6470         "NO delete child access"
6471 };
6472 static const true_false_string tfs_nt_access_mask_execute = {
6473         "EXECUTE access",
6474         "NO execute access"
6475 };
6476 static const true_false_string tfs_nt_access_mask_write_ea = {
6477         "WRITE EXTENDED ATTRIBUTES access",
6478         "NO write extended attributes access"
6479 };
6480 static const true_false_string tfs_nt_access_mask_read_ea = {
6481         "READ EXTENDED ATTRIBUTES access",
6482         "NO read extended attributes access"
6483 };
6484 static const true_false_string tfs_nt_access_mask_append = {
6485         "APPEND access",
6486         "NO append access"
6487 };
6488 static const true_false_string tfs_nt_access_mask_write = {
6489         "WRITE access",
6490         "NO write access"
6491 };
6492 static const true_false_string tfs_nt_access_mask_read = {
6493         "READ access",
6494         "NO read access"
6495 };
6496
6497 static const true_false_string tfs_nt_share_access_delete = {
6498         "Object can be shared for DELETE",
6499         "Object can NOT be shared for delete"
6500 };
6501 static const true_false_string tfs_nt_share_access_write = {
6502         "Object can be shared for WRITE",
6503         "Object can NOT be shared for write"
6504 };
6505 static const true_false_string tfs_nt_share_access_read = {
6506         "Object can be shared for READ",
6507         "Object can NOT be shared for read"
6508 };
6509
6510 static const value_string oplock_level_vals[] = {
6511         {0,     "No oplock granted"},
6512         {1,     "Exclusive oplock granted"},
6513         {2,     "Batch oplock granted"},
6514         {3,     "Level II oplock granted"},
6515         {0, NULL}
6516 };
6517
6518 static const value_string device_type_vals[] = {
6519         {0x00000001,    "Beep"},
6520         {0x00000002,    "CDROM"},
6521         {0x00000003,    "CDROM Filesystem"},
6522         {0x00000004,    "Controller"},
6523         {0x00000005,    "Datalink"},
6524         {0x00000006,    "Dfs"},
6525         {0x00000007,    "Disk"},
6526         {0x00000008,    "Disk Filesystem"},
6527         {0x00000009,    "Filesystem"},
6528         {0x0000000a,    "Inport Port"},
6529         {0x0000000b,    "Keyboard"},
6530         {0x0000000c,    "Mailslot"},
6531         {0x0000000d,    "MIDI-In"},
6532         {0x0000000e,    "MIDI-Out"},
6533         {0x0000000f,    "Mouse"},
6534         {0x00000010,    "Multi UNC Provider"},
6535         {0x00000011,    "Named Pipe"},
6536         {0x00000012,    "Network"},
6537         {0x00000013,    "Network Browser"},
6538         {0x00000014,    "Network Filesystem"},
6539         {0x00000015,    "NULL"},
6540         {0x00000016,    "Parallel Port"},
6541         {0x00000017,    "Physical card"},
6542         {0x00000018,    "Printer"},
6543         {0x00000019,    "Scanner"},
6544         {0x0000001a,    "Serial Mouse port"},
6545         {0x0000001b,    "Serial port"},
6546         {0x0000001c,    "Screen"},
6547         {0x0000001d,    "Sound"},
6548         {0x0000001e,    "Streams"},
6549         {0x0000001f,    "Tape"},
6550         {0x00000020,    "Tape Filesystem"},
6551         {0x00000021,    "Transport"},
6552         {0x00000022,    "Unknown"},
6553         {0x00000023,    "Video"},
6554         {0x00000024,    "Virtual Disk"},
6555         {0x00000025,    "WAVE-In"},
6556         {0x00000026,    "WAVE-Out"},
6557         {0x00000027,    "8042 Port"},
6558         {0x00000028,    "Network Redirector"},
6559         {0x00000029,    "Battery"},
6560         {0x0000002a,    "Bus Extender"},
6561         {0x0000002b,    "Modem"},
6562         {0x0000002c,    "VDM"},
6563         {0,     NULL}
6564 };
6565
6566 static const value_string is_directory_vals[] = {
6567         {0,     "This is NOT a directory"},
6568         {1,     "This is a DIRECTORY"},
6569         {0, NULL}
6570 };
6571
6572 typedef struct _nt_trans_data {
6573         int subcmd;
6574         guint32 sd_len;
6575         guint32 ea_len;
6576 } nt_trans_data;
6577
6578
6579
6580 static int
6581 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6582 {
6583         guint8 mask;
6584         proto_item *item = NULL;
6585         proto_tree *tree = NULL;
6586
6587         mask = tvb_get_guint8(tvb, offset);
6588
6589         if(parent_tree){
6590                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6591                         "Security Flags: 0x%02x", mask);
6592                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
6593         }
6594
6595         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
6596                 tvb, offset, 1, mask);
6597         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
6598                 tvb, offset, 1, mask);
6599
6600         offset += 1;
6601
6602         return offset;
6603 }
6604
6605 static int
6606 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6607 {
6608         guint32 mask;
6609         proto_item *item = NULL;
6610         proto_tree *tree = NULL;
6611
6612         mask = tvb_get_letohl(tvb, offset);
6613
6614         if(parent_tree){
6615                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6616                         "Share Access: 0x%08x", mask);
6617                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
6618         }
6619
6620         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
6621                 tvb, offset, 4, mask);
6622         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
6623                 tvb, offset, 4, mask);
6624         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
6625                 tvb, offset, 4, mask);
6626
6627         offset += 4;
6628
6629         return offset;
6630 }
6631
6632 /* FIXME: need to call dissect_nt_access_mask() instead */
6633
6634 static int
6635 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6636 {
6637         guint32 mask;
6638         proto_item *item = NULL;
6639         proto_tree *tree = NULL;
6640
6641         mask = tvb_get_letohl(tvb, offset);
6642
6643         if(parent_tree){
6644                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6645                         "Access Mask: 0x%08x", mask);
6646                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
6647         }
6648
6649         /*
6650          * Some of these bits come from
6651          *
6652          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6653          *
6654          * and others come from the section on ZwOpenFile in "Windows(R)
6655          * NT(R)/2000 Native API Reference".
6656          */
6657         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
6658                 tvb, offset, 4, mask);
6659         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
6660                 tvb, offset, 4, mask);
6661         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
6662                 tvb, offset, 4, mask);
6663         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
6664                 tvb, offset, 4, mask);
6665         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
6666                 tvb, offset, 4, mask);
6667         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
6668                 tvb, offset, 4, mask);
6669         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
6670                 tvb, offset, 4, mask);
6671         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
6672                 tvb, offset, 4, mask);
6673         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
6674                 tvb, offset, 4, mask);
6675         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
6676                 tvb, offset, 4, mask);
6677         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
6678                 tvb, offset, 4, mask);
6679         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
6680                 tvb, offset, 4, mask);
6681         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
6682                 tvb, offset, 4, mask);
6683         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
6684                 tvb, offset, 4, mask);
6685         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
6686                 tvb, offset, 4, mask);
6687         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
6688                 tvb, offset, 4, mask);
6689         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
6690                 tvb, offset, 4, mask);
6691         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
6692                 tvb, offset, 4, mask);
6693         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
6694                 tvb, offset, 4, mask);
6695         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
6696                 tvb, offset, 4, mask);
6697
6698         offset += 4;
6699
6700         return offset;
6701 }
6702
6703 static int
6704 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6705 {
6706         guint32 mask;
6707         proto_item *item = NULL;
6708         proto_tree *tree = NULL;
6709
6710         mask = tvb_get_letohl(tvb, offset);
6711
6712         if(parent_tree){
6713                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6714                         "Create Flags: 0x%08x", mask);
6715                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
6716         }
6717
6718         /*
6719          * XXX - it's 0x00000016 in at least one capture, but
6720          * Network Monitor doesn't say what the 0x00000010 bit is.
6721          * Does the Win32 API documentation, or NT Native API book,
6722          * suggest anything?
6723          */
6724         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
6725                 tvb, offset, 4, mask);
6726         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
6727                 tvb, offset, 4, mask);
6728         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
6729                 tvb, offset, 4, mask);
6730
6731         offset += 4;
6732
6733         return offset;
6734 }
6735
6736 /*
6737  * XXX - there are some more flags in the description of "ZwOpenFile()"
6738  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
6739  * the wire as well?  (The spec at
6740  *
6741  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6742  *
6743  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
6744  * via the SMB protocol.  The NT redirector should convert this option
6745  * to FILE_WRITE_THROUGH."
6746  *
6747  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
6748  * values one would infer from their position in the list of flags for
6749  * "ZwOpenFile()".  Most of the others probably have those values
6750  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
6751  * which might go over the wire (for the benefit of backup/restore software).
6752  */
6753 static const true_false_string tfs_nt_create_options_directory = {
6754         "File being created/opened must be a directory",
6755         "File being created/opened must not be a directory"
6756 };
6757 static const true_false_string tfs_nt_create_options_write_through = {
6758         "Writes should flush buffered data before completing",
6759         "Writes need not flush buffered data before completing"
6760 };
6761 static const true_false_string tfs_nt_create_options_sequential_only = {
6762         "The file will only be accessed sequentially",
6763         "The file might not only be accessed sequentially"
6764 };
6765 static const true_false_string tfs_nt_create_options_sync_io_alert = {
6766         "All operations SYNCHRONOUS, waits subject to termination from alert",
6767         "Operations NOT necessarily synchronous"
6768 };
6769 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
6770         "All operations SYNCHRONOUS, waits not subject to alert",
6771         "Operations NOT necessarily synchronous"
6772 };
6773 static const true_false_string tfs_nt_create_options_non_directory = {
6774         "File being created/opened must not be a directory",
6775         "File being created/opened must be a directory"
6776 };
6777 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
6778         "The client does not understand extended attributes",
6779         "The client understands extended attributes"
6780 };
6781 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
6782         "The client understands only 8.3 file names",
6783         "The client understands long file names"
6784 };
6785 static const true_false_string tfs_nt_create_options_random_access = {
6786         "The file will be accessed randomly",
6787         "The file will not be accessed randomly"
6788 };
6789 static const true_false_string tfs_nt_create_options_delete_on_close = {
6790         "The file should be deleted when it is closed",
6791         "The file should not be deleted when it is closed"
6792 };
6793
6794 static int
6795 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6796 {
6797         guint32 mask;
6798         proto_item *item = NULL;
6799         proto_tree *tree = NULL;
6800
6801         mask = tvb_get_letohl(tvb, offset);
6802
6803         if(parent_tree){
6804                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6805                         "Create Options: 0x%08x", mask);
6806                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
6807         }
6808
6809         /*
6810          * From
6811          *
6812          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6813          */
6814         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
6815                 tvb, offset, 4, mask);
6816         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
6817                 tvb, offset, 4, mask);
6818         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
6819                 tvb, offset, 4, mask);
6820         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
6821                 tvb, offset, 4, mask);
6822         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
6823                 tvb, offset, 4, mask);
6824         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
6825                 tvb, offset, 4, mask);
6826         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
6827                 tvb, offset, 4, mask);
6828         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
6829                 tvb, offset, 4, mask);
6830         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
6831                 tvb, offset, 4, mask);
6832         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
6833                 tvb, offset, 4, mask);
6834
6835         offset += 4;
6836
6837         return offset;
6838 }
6839
6840 static int
6841 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6842 {
6843         guint32 mask;
6844         proto_item *item = NULL;
6845         proto_tree *tree = NULL;
6846
6847         mask = tvb_get_letohl(tvb, offset);
6848
6849         if(parent_tree){
6850                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6851                         "Completion Filter: 0x%08x", mask);
6852                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
6853         }
6854
6855         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
6856                 tvb, offset, 4, mask);
6857         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
6858                 tvb, offset, 4, mask);
6859         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
6860                 tvb, offset, 4, mask);
6861         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
6862                 tvb, offset, 4, mask);
6863         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
6864                 tvb, offset, 4, mask);
6865         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
6866                 tvb, offset, 4, mask);
6867         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
6868                 tvb, offset, 4, mask);
6869         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
6870                 tvb, offset, 4, mask);
6871         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
6872                 tvb, offset, 4, mask);
6873         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
6874                 tvb, offset, 4, mask);
6875         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
6876                 tvb, offset, 4, mask);
6877         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
6878                 tvb, offset, 4, mask);
6879
6880         offset += 4;
6881         return offset;
6882 }
6883
6884 static int
6885 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6886 {
6887         guint8 mask;
6888         proto_item *item = NULL;
6889         proto_tree *tree = NULL;
6890
6891         mask = tvb_get_guint8(tvb, offset);
6892
6893         if(parent_tree){
6894                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6895                         "Completion Filter: 0x%02x", mask);
6896                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
6897         }
6898
6899         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
6900                 tvb, offset, 1, mask);
6901
6902         offset += 1;
6903         return offset;
6904 }
6905
6906 /*
6907  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
6908  * Native API Reference".
6909  */
6910 static const true_false_string tfs_nt_qsd_owner = {
6911         "Requesting OWNER security information",
6912         "NOT requesting owner security information",
6913 };
6914
6915 static const true_false_string tfs_nt_qsd_group = {
6916         "Requesting GROUP security information",
6917         "NOT requesting group security information",
6918 };
6919
6920 static const true_false_string tfs_nt_qsd_dacl = {
6921         "Requesting DACL security information",
6922         "NOT requesting DACL security information",
6923 };
6924
6925 static const true_false_string tfs_nt_qsd_sacl = {
6926         "Requesting SACL security information",
6927         "NOT requesting SACL security information",
6928 };
6929
6930 #define NT_QSD_OWNER    0x00000001
6931 #define NT_QSD_GROUP    0x00000002
6932 #define NT_QSD_DACL     0x00000004
6933 #define NT_QSD_SACL     0x00000008
6934
6935 static int
6936 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6937 {
6938         guint32 mask;
6939         proto_item *item = NULL;
6940         proto_tree *tree = NULL;
6941
6942         mask = tvb_get_letohl(tvb, offset);
6943
6944         if(parent_tree){
6945                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6946                         "Security Information: 0x%08x", mask);
6947                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
6948         }
6949
6950         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
6951                 tvb, offset, 4, mask);
6952         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
6953                 tvb, offset, 4, mask);
6954         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
6955                 tvb, offset, 4, mask);
6956         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
6957                 tvb, offset, 4, mask);
6958
6959         offset += 4;
6960
6961         return offset;
6962 }
6963
6964 static void
6965 free_g_string(void *arg)
6966 {
6967         g_string_free(arg, TRUE);
6968 }
6969
6970 /* Dissect a NT SID.  Label it with 'name' and return a string version of
6971    the SID in the 'sid_str' parameter which must be freed by the caller. */
6972
6973 int
6974 dissect_nt_sid(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name,
6975                char **sid_str)
6976 {
6977         proto_item *item = NULL;
6978         proto_tree *tree = NULL;
6979         int old_offset = offset, sa_offset = offset;
6980         gboolean rid_present;
6981         guint rid=0;
6982         int rid_offset=0;
6983         guint8 revision;
6984         int rev_offset;
6985         guint8 num_auth;
6986         int na_offset;
6987         guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
6988         int i;
6989         GString *gstr;
6990         char sid_string[245];
6991         char *sid_name;
6992
6993         /* revision of sid */
6994         revision = tvb_get_guint8(tvb, offset);
6995         rev_offset = offset;
6996         offset += 1;
6997
6998         switch(revision){
6999         case 1:
7000         case 2:  /* Not sure what the different revision numbers mean */
7001           /* number of authorities*/
7002           num_auth = tvb_get_guint8(tvb, offset);
7003           na_offset = offset;
7004           offset += 1;
7005
7006           /* XXX perhaps we should have these thing searchable?
7007              a new FT_xxx thingie? SMB is quite common!*/
7008           /* identifier authorities */
7009
7010           for(i=0;i<6;i++){
7011             auth = (auth << 8) + tvb_get_guint8(tvb, offset);
7012
7013             offset++;
7014           }
7015
7016           sa_offset = offset;
7017
7018           gstr = g_string_new("");
7019
7020           CLEANUP_PUSH(free_g_string, gstr);
7021
7022           /* sub authorities, leave RID to last */
7023           for(i=0; i < (num_auth > 4?(num_auth - 1):num_auth); i++){
7024             /*
7025              * XXX should not be letohl but native byteorder according to
7026              * Samba header files.
7027              *
7028              * However, considering that there were never any NT ports
7029              * to big-endian platforms (PowerPC and MIPS ran little-endian,
7030              * and IA-64 runs little-endian, as does x86-64), we can (?)
7031              * assume that non le byte encodings will be "uncommon"?
7032              */
7033              g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"),
7034                   tvb_get_letohl(tvb, offset));
7035              offset+=4;
7036           }
7037
7038
7039           if (num_auth > 4) {
7040             rid = tvb_get_letohl(tvb, offset);
7041             rid_present=TRUE;
7042             rid_offset=offset;
7043             offset+=4;
7044             sprintf(sid_string, "S-1-%u-%s-%u", auth, gstr->str, rid);
7045           } else {
7046             rid_present=FALSE;
7047             sprintf(sid_string, "S-1-%u-%s", auth, gstr->str);
7048           }
7049
7050           sid_name=NULL;
7051           if(sid_name_snooping){
7052             sid_name=find_sid_name(sid_string);
7053           }
7054
7055           if(parent_tree){
7056             if(sid_name){
7057               item = proto_tree_add_string_format(parent_tree, hf_smb_sid, tvb, old_offset, offset-old_offset, sid_string, "%s: %s (%s)", name, sid_string, sid_name);
7058             } else {
7059               item = proto_tree_add_string_format(parent_tree, hf_smb_sid, tvb, old_offset, offset-old_offset, sid_string, "%s: %s", name, sid_string);
7060             }
7061             tree = proto_item_add_subtree(item, ett_smb_sid);
7062           }
7063
7064           proto_tree_add_item(tree, hf_smb_sid_revision, tvb, rev_offset, 1, TRUE);
7065           proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, na_offset, 1, TRUE);
7066           proto_tree_add_text(tree, tvb, na_offset+1, 6, "Authority: %u", auth);
7067           proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
7068
7069           if(rid_present){
7070             proto_tree_add_text(tree, tvb, rid_offset, 4, "RID: %u", rid);
7071           }
7072
7073           if(sid_str){
7074             *sid_str = g_strdup(sid_string);
7075           }
7076
7077           CLEANUP_CALL_AND_POP;
7078         }
7079
7080
7081         return offset;
7082 }
7083
7084
7085 static const value_string ace_type_vals[] = {
7086   { 0, "Access Allowed"},
7087   { 1, "Access Denied"},
7088   { 2, "System Audit"},
7089   { 3, "System Alarm"},
7090   { 0, NULL}
7091 };
7092 static const true_false_string tfs_ace_flags_object_inherit = {
7093   "Subordinate files will inherit this ACE",
7094   "Subordinate files will not inherit this ACE"
7095 };
7096 static const true_false_string tfs_ace_flags_container_inherit = {
7097   "Subordinate containers will inherit this ACE",
7098   "Subordinate containers will not inherit this ACE"
7099 };
7100 static const true_false_string tfs_ace_flags_non_propagate_inherit = {
7101   "Subordinate object will not propagate the inherited ACE further",
7102   "Subordinate object will propagate the inherited ACE further"
7103 };
7104 static const true_false_string tfs_ace_flags_inherit_only = {
7105   "This ACE does not apply to the current object",
7106   "This ACE applies to the current object"
7107 };
7108 static const true_false_string tfs_ace_flags_inherited_ace = {
7109   "This ACE was inherited from its parent object",
7110   "This ACE was not inherited from its parent object"
7111 };
7112 static const true_false_string tfs_ace_flags_successful_access = {
7113   "Successful accesses will be audited",
7114   "Successful accesses will not be audited"
7115 };
7116 static const true_false_string tfs_ace_flags_failed_access = {
7117   "Failed accesses will be audited",
7118   "Failed accesses will not be audited"
7119 };
7120
7121 #define APPEND_ACE_TEXT(flag, item, string) \
7122         if(flag){                                                       \
7123                 if(item)                                                \
7124                         proto_item_append_text(item, string, sep);      \
7125                 sep = ", ";                                             \
7126         }
7127
7128 static int
7129 dissect_nt_v2_ace_flags(tvbuff_t *tvb, int offset, proto_tree *parent_tree,
7130                         guint8 *data)
7131 {
7132         proto_item *item = NULL;
7133         proto_tree *tree = NULL;
7134         guint8 mask;
7135         char *sep = " ";
7136
7137         mask = tvb_get_guint8(tvb, offset);
7138
7139         if (data)
7140                 *data = mask;
7141
7142
7143         if(parent_tree){
7144                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7145                                            "NT ACE Flags: 0x%02x", mask);
7146                 tree = proto_item_add_subtree(item, ett_smb_ace_flags);
7147         }
7148
7149         proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
7150                        tvb, offset, 1, mask);
7151         APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
7152
7153         proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
7154                        tvb, offset, 1, mask);
7155         APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
7156
7157         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
7158                        tvb, offset, 1, mask);
7159         APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
7160
7161         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
7162                        tvb, offset, 1, mask);
7163         APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
7164
7165         proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
7166                        tvb, offset, 1, mask);
7167         APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
7168
7169         proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
7170                        tvb, offset, 1, mask);
7171         APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
7172
7173         proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
7174                        tvb, offset, 1, mask);
7175         APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
7176
7177
7178         offset += 1;
7179         return offset;
7180 }
7181
7182 /* Dissect an access mask.  All this stuff is kind of explained at MSDN:
7183
7184 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/windows_2000_windows_nt_access_mask_format.asp
7185
7186 */
7187
7188 static gint ett_nt_access_mask = -1;
7189 static gint ett_nt_access_mask_generic = -1;
7190 static gint ett_nt_access_mask_standard = -1;
7191 static gint ett_nt_access_mask_specific = -1;
7192
7193 static int hf_access_sacl = -1;
7194 static int hf_access_maximum_allowed = -1;
7195 static int hf_access_generic_read = -1;
7196 static int hf_access_generic_write = -1;
7197 static int hf_access_generic_execute = -1;
7198 static int hf_access_generic_all = -1;
7199 static int hf_access_standard_delete = -1;
7200 static int hf_access_standard_read_control = -1;
7201 static int hf_access_standard_synchronise = -1;
7202 static int hf_access_standard_write_dac = -1;
7203 static int hf_access_standard_write_owner = -1;
7204 static int hf_access_specific_15 = -1;
7205 static int hf_access_specific_14 = -1;
7206 static int hf_access_specific_13 = -1;
7207 static int hf_access_specific_12 = -1;
7208 static int hf_access_specific_11 = -1;
7209 static int hf_access_specific_10 = -1;
7210 static int hf_access_specific_9 = -1;
7211 static int hf_access_specific_8 = -1;
7212 static int hf_access_specific_7 = -1;
7213 static int hf_access_specific_6 = -1;
7214 static int hf_access_specific_5 = -1;
7215 static int hf_access_specific_4 = -1;
7216 static int hf_access_specific_3 = -1;
7217 static int hf_access_specific_2 = -1;
7218 static int hf_access_specific_1 = -1;
7219 static int hf_access_specific_0 = -1;
7220
7221 int
7222 dissect_nt_access_mask(tvbuff_t *tvb, gint offset, packet_info *pinfo,
7223                        proto_tree *tree, char *drep, int hfindex,
7224                        nt_access_mask_fn_t *specific_rights_fn,
7225                        char *specific_rights_name)
7226 {
7227         proto_item *item;
7228         proto_tree *subtree, *generic, *standard, *specific;
7229         guint32 access;
7230
7231         if (drep != NULL) {
7232                 /*
7233                  * Called from a DCE RPC protocol dissector, for a
7234                  * protocol where a 32-bit NDR integer contains
7235                  * an NT access mask; extract the access mask
7236                  * with an NDR call.
7237                  */
7238                 offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
7239                                             hfindex, &access);
7240         } else {
7241                 /*
7242                  * Called from SMB, where the access mask is just a
7243                  * 4-byte little-endian quantity with no special
7244                  * NDR alignment requirement; extract it with
7245                  * "tvb_get_letohl()".
7246                  */
7247                 access = tvb_get_letohl(tvb, offset);
7248                 offset += 4;
7249         }
7250
7251         item = proto_tree_add_uint(tree, hfindex, tvb, offset - 4, 4, access);
7252
7253         subtree = proto_item_add_subtree(item, ett_nt_access_mask);
7254
7255         /* Generic access rights */
7256
7257         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7258                                    "Generic rights: 0x%08x",
7259                                    access & GENERIC_RIGHTS_MASK);
7260
7261         generic = proto_item_add_subtree(item, ett_nt_access_mask_generic);
7262
7263         proto_tree_add_boolean(
7264                 generic, hf_access_generic_read, tvb, offset - 4, 4,
7265                 access);
7266
7267         proto_tree_add_boolean(
7268                 generic, hf_access_generic_write, tvb, offset - 4, 4,
7269                 access);
7270
7271         proto_tree_add_boolean(
7272                 generic, hf_access_generic_execute, tvb, offset - 4, 4,
7273                 access);
7274
7275         proto_tree_add_boolean(
7276                 generic, hf_access_generic_all, tvb, offset - 4, 4,
7277                 access);
7278
7279         /* Reserved (??) */
7280
7281         proto_tree_add_boolean(
7282                 subtree, hf_access_maximum_allowed, tvb, offset - 4, 4,
7283                 access);
7284
7285         /* Access system security */
7286
7287         proto_tree_add_boolean(
7288                 subtree, hf_access_sacl, tvb, offset - 4, 4,
7289                 access);
7290
7291         /* Standard access rights */
7292
7293         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7294                                    "Standard rights: 0x%08x",
7295                                    access & STANDARD_RIGHTS_MASK);
7296
7297         standard = proto_item_add_subtree(item, ett_nt_access_mask_standard);
7298
7299         proto_tree_add_boolean(
7300                 standard, hf_access_standard_synchronise, tvb, offset - 4, 4,
7301                 access);
7302
7303         proto_tree_add_boolean(
7304                 standard, hf_access_standard_write_owner, tvb, offset - 4, 4,
7305                 access);
7306
7307         proto_tree_add_boolean(
7308                 standard, hf_access_standard_write_dac, tvb, offset - 4, 4,
7309                 access);
7310
7311         proto_tree_add_boolean(
7312                 standard, hf_access_standard_read_control, tvb, offset - 4, 4,
7313                 access);
7314
7315         proto_tree_add_boolean(
7316                 standard, hf_access_standard_delete, tvb, offset - 4, 4,
7317                 access);
7318
7319         /* Specific access rights.  Call the specific_rights_fn
7320            pointer if we have one, otherwise just display bits 0-15 in
7321            boring fashion. */
7322
7323         if (specific_rights_name)
7324                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7325                                            "%s specific rights: 0x%08x",
7326                                            specific_rights_name,
7327                                            access & SPECIFIC_RIGHTS_MASK);
7328         else
7329                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7330                                            "Specific rights: 0x%08x",
7331                                            access & SPECIFIC_RIGHTS_MASK);
7332
7333         specific = proto_item_add_subtree(item, ett_nt_access_mask_specific);
7334
7335         if (specific_rights_fn) {
7336                 specific_rights_fn(tvb, offset - 4, specific, access);
7337                 return offset;
7338         }
7339
7340         proto_tree_add_boolean(
7341                 specific, hf_access_specific_15, tvb, offset - 4, 4,
7342                 access);
7343
7344         proto_tree_add_boolean(
7345                 specific, hf_access_specific_14, tvb, offset - 4, 4,
7346                 access);
7347
7348         proto_tree_add_boolean(
7349                 specific, hf_access_specific_13, tvb, offset - 4, 4,
7350                 access);
7351
7352         proto_tree_add_boolean(
7353                 specific, hf_access_specific_12, tvb, offset - 4, 4,
7354                 access);
7355
7356         proto_tree_add_boolean(
7357                 specific, hf_access_specific_11, tvb, offset - 4, 4,
7358                 access);
7359
7360         proto_tree_add_boolean(
7361                 specific, hf_access_specific_10, tvb, offset - 4, 4,
7362                 access);
7363
7364         proto_tree_add_boolean(
7365                 specific, hf_access_specific_9, tvb, offset - 4, 4,
7366                 access);
7367
7368         proto_tree_add_boolean(
7369                 specific, hf_access_specific_8, tvb, offset - 4, 4,
7370                 access);
7371
7372         proto_tree_add_boolean(
7373                 specific, hf_access_specific_7, tvb, offset - 4, 4,
7374                 access);
7375
7376         proto_tree_add_boolean(
7377                 specific, hf_access_specific_6, tvb, offset - 4, 4,
7378                 access);
7379
7380         proto_tree_add_boolean(
7381                 specific, hf_access_specific_5, tvb, offset - 4, 4,
7382                 access);
7383
7384         proto_tree_add_boolean(
7385                 specific, hf_access_specific_4, tvb, offset - 4, 4,
7386                 access);
7387
7388         proto_tree_add_boolean(
7389                 specific, hf_access_specific_3, tvb, offset - 4, 4,
7390                 access);
7391
7392         proto_tree_add_boolean(
7393                 specific, hf_access_specific_2, tvb, offset - 4, 4,
7394                 access);
7395
7396         proto_tree_add_boolean(
7397                 specific, hf_access_specific_1, tvb, offset - 4, 4,
7398                 access);
7399
7400         proto_tree_add_boolean(
7401                 specific, hf_access_specific_0, tvb, offset - 4, 4,
7402                 access);
7403
7404         return offset;
7405 }
7406
7407 static int hf_smb_access_mask = -1;
7408
7409 static int
7410 dissect_nt_v2_ace(tvbuff_t *tvb, int offset, packet_info *pinfo,
7411                   proto_tree *parent_tree, char *drep,
7412                   nt_access_mask_fn_t *specific_rights_fn,
7413                   char *specific_rights_name)
7414 {
7415         proto_item *item = NULL;
7416         proto_tree *tree = NULL;
7417         int old_offset = offset;
7418         guint16 size;
7419         char *sid_str;
7420         guint8 type;
7421         guint8 flags;
7422
7423         if(parent_tree){
7424                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7425                                            "NT ACE: ");
7426                 tree = proto_item_add_subtree(item, ett_smb_ace);
7427         }
7428
7429         /* type */
7430         type = tvb_get_guint8(tvb, offset);
7431         proto_tree_add_uint(tree, hf_smb_ace_type, tvb, offset, 1, type);
7432         offset += 1;
7433
7434         /* flags */
7435         offset = dissect_nt_v2_ace_flags(tvb, offset, tree, &flags);
7436
7437         /* size */
7438         size = tvb_get_letohs(tvb, offset);
7439         proto_tree_add_uint(tree, hf_smb_ace_size, tvb, offset, 2, size);
7440         offset += 2;
7441
7442         /* access mask */
7443         offset = dissect_nt_access_mask(
7444                 tvb, offset, pinfo, tree, drep, hf_smb_access_mask, 
7445                 specific_rights_fn, specific_rights_name);
7446
7447         /* SID */
7448         offset = dissect_nt_sid(tvb, offset, tree, "ACE", &sid_str);
7449
7450         if (item)
7451                 proto_item_append_text(
7452                         item, "%s, flags 0x%02x, %s", sid_str, flags,
7453                         val_to_str(type, ace_type_vals, "Unknown ACE type (0x%02x)"));
7454
7455         g_free(sid_str);
7456
7457         proto_item_set_len(item, offset-old_offset);
7458
7459         /* Sometimes there is some spare space at the end of the ACE so use
7460            the size field to work out where the end is. */
7461
7462         return old_offset + size;
7463 }
7464
7465 static int
7466 dissect_nt_acl(tvbuff_t *tvb, int offset, packet_info *pinfo,
7467                proto_tree *parent_tree, char *drep, char *name,
7468                nt_access_mask_fn_t *specific_rights_fn,
7469                char *specific_rights_name)
7470 {
7471         proto_item *item = NULL;
7472         proto_tree *tree = NULL;
7473         int old_offset = offset;
7474         guint16 revision;
7475         guint32 num_aces;
7476
7477         if(parent_tree){
7478                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7479                                            "NT %s ACL", name);
7480                 tree = proto_item_add_subtree(item, ett_smb_acl);
7481         }
7482
7483         /* revision */
7484         revision = tvb_get_letohs(tvb, offset);
7485         proto_tree_add_uint(tree, hf_smb_acl_revision,
7486                 tvb, offset, 2, revision);
7487         offset += 2;
7488
7489         switch(revision){
7490         case 2:  /* only version we will ever see of this structure?*/
7491         case 3:
7492           /* size */
7493           proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
7494           offset += 2;
7495
7496           /* number of ace structures */
7497           num_aces = tvb_get_letohl(tvb, offset);
7498           proto_tree_add_uint(tree, hf_smb_acl_num_aces,
7499                               tvb, offset, 4, num_aces);
7500           offset += 4;
7501
7502           while(num_aces--){
7503             offset=dissect_nt_v2_ace(
7504                     tvb, offset, pinfo, tree, drep, specific_rights_fn,
7505                     specific_rights_name);
7506           }
7507         }
7508
7509         proto_item_set_len(item, offset-old_offset);
7510         return offset;
7511 }
7512
7513 static const true_false_string tfs_sec_desc_type_owner_defaulted = {
7514   "OWNER is DEFAULTED",
7515   "Owner is NOT defaulted"
7516 };
7517 static const true_false_string tfs_sec_desc_type_group_defaulted = {
7518   "GROUP is DEFAULTED",
7519   "Group is NOT defaulted"
7520 };
7521 static const true_false_string tfs_sec_desc_type_dacl_present = {
7522   "DACL is PRESENT",
7523   "DACL is NOT present"
7524 };
7525 static const true_false_string tfs_sec_desc_type_dacl_defaulted = {
7526   "DACL is DEFAULTED",
7527   "DACL is NOT defaulted"
7528 };
7529 static const true_false_string tfs_sec_desc_type_sacl_present = {
7530   "SACL is PRESENT",
7531   "SACL is NOT present"
7532 };
7533 static const true_false_string tfs_sec_desc_type_sacl_defaulted = {
7534   "SACL is DEFAULTED",
7535   "SACL is NOT defaulted"
7536 };
7537 static const true_false_string tfs_sec_desc_type_dacl_auto_inherit_req = {
7538   "DACL has AUTO INHERIT REQUIRED",
7539   "DACL does NOT require auto inherit"
7540 };
7541 static const true_false_string tfs_sec_desc_type_sacl_auto_inherit_req = {
7542   "SACL has AUTO INHERIT REQUIRED",
7543   "SACL does NOT require auto inherit"
7544 };
7545 static const true_false_string tfs_sec_desc_type_dacl_auto_inherited = {
7546   "DACL is AUTO INHERITED",
7547   "DACL is NOT auto inherited"
7548 };
7549 static const true_false_string tfs_sec_desc_type_sacl_auto_inherited = {
7550   "SACL is AUTO INHERITED",
7551   "SACL is NOT auto inherited"
7552 };
7553 static const true_false_string tfs_sec_desc_type_dacl_protected = {
7554   "The DACL is PROTECTED",
7555   "The DACL is NOT protected"
7556 };
7557 static const true_false_string tfs_sec_desc_type_sacl_protected = {
7558   "The SACL is PROTECTED",
7559   "The SACL is NOT protected"
7560 };
7561 static const true_false_string tfs_sec_desc_type_self_relative = {
7562   "This SecDesc is SELF RELATIVE",
7563   "This SecDesc is NOT self relative"
7564 };
7565
7566
7567 static int
7568 dissect_nt_sec_desc_type(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7569 {
7570         proto_item *item = NULL;
7571         proto_tree *tree = NULL;
7572         guint16 mask;
7573
7574         mask = tvb_get_letohs(tvb, offset);
7575         if(parent_tree){
7576                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7577                                            "Type: 0x%04x", mask);
7578                 tree = proto_item_add_subtree(item, ett_smb_sec_desc_type);
7579         }
7580
7581         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_self_relative,
7582                                tvb, offset, 2, mask);
7583         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_protected,
7584                                tvb, offset, 2, mask);
7585         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_protected,
7586                                tvb, offset, 2, mask);
7587         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherited,
7588                                tvb, offset, 2, mask);
7589         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherited,
7590                                tvb, offset, 2, mask);
7591         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherit_req,
7592                                tvb, offset, 2, mask);
7593         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherit_req,
7594                                tvb, offset, 2, mask);
7595         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_defaulted,
7596                                tvb, offset, 2, mask);
7597         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_present,
7598                                tvb, offset, 2, mask);
7599         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_defaulted,
7600                                tvb, offset, 2, mask);
7601         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_present,
7602                                tvb, offset, 2, mask);
7603         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_group_defaulted,
7604                                tvb, offset, 2, mask);
7605         proto_tree_add_boolean(tree, hf_smb_sec_desc_type_owner_defaulted,
7606                                tvb, offset, 2, mask);
7607
7608
7609         offset += 2;
7610         return offset;
7611 }
7612
7613 int
7614 dissect_nt_sec_desc(tvbuff_t *tvb, int offset, packet_info *pinfo,
7615                     proto_tree *parent_tree, char *drep, int len, 
7616                     nt_access_mask_fn_t *specific_rights_fn,
7617                     char *specific_rights_name)
7618 {
7619         proto_item *item = NULL;
7620         proto_tree *tree = NULL;
7621         guint8 revision;
7622         int old_offset = offset;
7623         guint32 owner_sid_offset;
7624         guint32 group_sid_offset;
7625         guint32 sacl_offset;
7626         guint32 dacl_offset;
7627
7628         if(parent_tree){
7629                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7630                                            "NT Security Descriptor");
7631                 tree = proto_item_add_subtree(item, ett_smb_sec_desc);
7632         }
7633
7634         /* revision */
7635         revision = tvb_get_guint8(tvb, offset);
7636         proto_tree_add_uint(tree, hf_smb_sec_desc_revision,
7637                 tvb, offset, 1, revision);
7638         offset += 1;
7639
7640         /* next byte should be zero, for now just ignore it */
7641         offset += 1;
7642
7643
7644         switch(revision){
7645         case 1:  /* only version we will ever see of this structure?*/
7646           /* type */
7647           offset = dissect_nt_sec_desc_type(tvb, offset, tree);
7648
7649           /* offset to owner sid */
7650           owner_sid_offset = tvb_get_letohl(tvb, offset);
7651           proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %u", owner_sid_offset);
7652           offset += 4;
7653
7654           /* offset to group sid */
7655           group_sid_offset = tvb_get_letohl(tvb, offset);
7656           proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %u", group_sid_offset);
7657           offset += 4;
7658
7659           /* offset to sacl */
7660           sacl_offset = tvb_get_letohl(tvb, offset);
7661           proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %u", sacl_offset);
7662           offset += 4;
7663
7664           /* offset to dacl */
7665           dacl_offset = tvb_get_letohl(tvb, offset);
7666           proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %u", dacl_offset);
7667           offset += 4;
7668
7669           /*owner SID*/
7670           if(owner_sid_offset){
7671             if (len == -1)
7672               offset = dissect_nt_sid(tvb, offset, tree, "Owner", NULL);
7673             else
7674               dissect_nt_sid(
7675                       tvb, old_offset+owner_sid_offset, tree, "Owner", NULL);
7676           }
7677
7678           /*group SID*/
7679           if(group_sid_offset){
7680             dissect_nt_sid(
7681                     tvb, old_offset+group_sid_offset, tree, "Group", NULL);
7682           }
7683
7684           /* sacl */
7685           if(sacl_offset){
7686             dissect_nt_acl(tvb, old_offset+sacl_offset, pinfo, tree, 
7687                            drep, "System (SACL)", specific_rights_fn,
7688                            specific_rights_name);
7689           }
7690
7691           /* dacl */
7692           if(dacl_offset){
7693             dissect_nt_acl(tvb, old_offset+dacl_offset, pinfo, tree, 
7694                            drep, "User (DACL)", specific_rights_fn,
7695                            specific_rights_name);
7696           }
7697
7698         }
7699
7700         return offset+len;
7701 }
7702
7703 static int
7704 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
7705 {
7706         int old_offset, old_sid_offset;
7707         guint32 qsize;
7708
7709         do {
7710                 old_offset=offset;
7711
7712                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7713                 qsize=tvb_get_letohl(tvb, offset);
7714                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
7715                 COUNT_BYTES_TRANS_SUBR(4);
7716
7717                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7718                 /* length of SID */
7719                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7720                 COUNT_BYTES_TRANS_SUBR(4);
7721
7722                 /* 16 unknown bytes */
7723                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7724                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7725                             offset, 8, TRUE);
7726                 COUNT_BYTES_TRANS_SUBR(8);
7727
7728                 /* number of bytes for used quota */
7729                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7730                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
7731                 COUNT_BYTES_TRANS_SUBR(8);
7732
7733                 /* number of bytes for quota warning */
7734                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7735                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
7736                 COUNT_BYTES_TRANS_SUBR(8);
7737
7738                 /* number of bytes for quota limit */
7739                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7740                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
7741                 COUNT_BYTES_TRANS_SUBR(8);
7742
7743                 /* SID of the user */
7744                 old_sid_offset=offset;
7745                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL);
7746                 *bcp -= (offset-old_sid_offset);
7747
7748                 if(qsize){
7749                         offset = old_offset+qsize;
7750                 }
7751         }while(qsize);
7752
7753
7754         return offset;
7755 }
7756
7757
7758 static int
7759 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
7760 {
7761         proto_item *item = NULL;
7762         proto_tree *tree = NULL;
7763         smb_info_t *si;
7764         int old_offset = offset;
7765         guint16 bcp=bc; /* XXX fixme */
7766
7767         si = (smb_info_t *)pinfo->private_data;
7768
7769         if(parent_tree){
7770                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
7771                                 "%s Data",
7772                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7773                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7774         }
7775
7776         switch(ntd->subcmd){
7777         case NT_TRANS_CREATE:
7778                 /* security descriptor */
7779                 if(ntd->sd_len){
7780                         offset = dissect_nt_sec_desc(
7781                                 tvb, offset, pinfo, tree, NULL, ntd->sd_len, 
7782                                 NULL, NULL);
7783                 }
7784
7785                 /* extended attributes */
7786                 if(ntd->ea_len){
7787                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
7788                         offset += ntd->ea_len;
7789                 }
7790
7791                 break;
7792         case NT_TRANS_IOCTL:
7793                 /* ioctl data */
7794                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
7795                 offset += bc;
7796
7797                 break;
7798         case NT_TRANS_SSD:
7799                 offset = dissect_nt_sec_desc(
7800                         tvb, offset, pinfo, tree, NULL, bc, NULL, NULL);
7801                 break;
7802         case NT_TRANS_NOTIFY:
7803                 break;
7804         case NT_TRANS_RENAME:
7805                 /* XXX not documented */
7806                 break;
7807         case NT_TRANS_QSD:
7808                 break;
7809         case NT_TRANS_GET_USER_QUOTA:
7810                 /* unknown 4 bytes */
7811                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7812                             offset, 4, TRUE);
7813                 offset += 4;
7814
7815                 /* length of SID */
7816                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7817                 offset +=4;
7818
7819                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL);
7820                 break;
7821         case NT_TRANS_SET_USER_QUOTA:
7822                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
7823                 break;
7824         }
7825
7826         /* ooops there were data we didnt know how to process */
7827         if((offset-old_offset) < bc){
7828                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
7829                     bc - (offset-old_offset), TRUE);
7830                 offset += bc - (offset-old_offset);
7831         }
7832
7833         return offset;
7834 }
7835
7836 static int
7837 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)
7838 {
7839         proto_item *item = NULL;
7840         proto_tree *tree = NULL;
7841         smb_info_t *si;
7842         guint32 fn_len;
7843         const char *fn;
7844
7845         si = (smb_info_t *)pinfo->private_data;
7846
7847         if(parent_tree){
7848                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7849                                 "%s Parameters",
7850                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7851                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7852         }
7853
7854         switch(ntd->subcmd){
7855         case NT_TRANS_CREATE:
7856                 /* Create flags */
7857                 offset = dissect_nt_create_bits(tvb, tree, offset);
7858                 bc -= 4;
7859
7860                 /* root directory fid */
7861                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
7862                 COUNT_BYTES(4);
7863
7864                 /* nt access mask */
7865                 offset = dissect_smb_access_mask(tvb, tree, offset);
7866                 bc -= 4;
7867
7868                 /* allocation size */
7869                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7870                 COUNT_BYTES(8);
7871
7872                 /* Extended File Attributes */
7873                 offset = dissect_file_ext_attr(tvb, tree, offset);
7874                 bc -= 4;
7875
7876                 /* share access */
7877                 offset = dissect_nt_share_access(tvb, tree, offset);
7878                 bc -= 4;
7879
7880                 /* create disposition */
7881                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
7882                 COUNT_BYTES(4);
7883
7884                 /* create options */
7885                 offset = dissect_nt_create_options(tvb, tree, offset);
7886                 bc -= 4;
7887
7888                 /* sd length */
7889                 ntd->sd_len = tvb_get_letohl(tvb, offset);
7890                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
7891                 COUNT_BYTES(4);
7892
7893                 /* ea length */
7894                 ntd->ea_len = tvb_get_letohl(tvb, offset);
7895                 proto_tree_add_uint(tree, hf_smb_ea_length, tvb, offset, 4, ntd->ea_len);
7896                 COUNT_BYTES(4);
7897
7898                 /* file name len */
7899                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
7900                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
7901                 COUNT_BYTES(4);
7902
7903                 /* impersonation level */
7904                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
7905                 COUNT_BYTES(4);
7906
7907                 /* security flags */
7908                 offset = dissect_nt_security_flags(tvb, tree, offset);
7909                 bc -= 1;
7910
7911                 /* file name */
7912                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
7913                 if (fn != NULL) {
7914                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7915                                 fn);
7916                         COUNT_BYTES(fn_len);
7917                 }
7918
7919                 break;
7920         case NT_TRANS_IOCTL:
7921                 break;
7922         case NT_TRANS_SSD: {
7923                 guint16 fid;
7924
7925                 /* fid */
7926                 fid = tvb_get_letohs(tvb, offset);
7927                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7928                 offset += 2;
7929
7930                 /* 2 reserved bytes */
7931                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7932                 offset += 2;
7933
7934                 /* security information */
7935                 offset = dissect_security_information_mask(tvb, tree, offset);
7936                 break;
7937         }
7938         case NT_TRANS_NOTIFY:
7939                 break;
7940         case NT_TRANS_RENAME:
7941                 /* XXX not documented */
7942                 break;
7943         case NT_TRANS_QSD: {
7944                 guint16 fid;
7945
7946                 /* fid */
7947                 fid = tvb_get_letohs(tvb, offset);
7948                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7949                 offset += 2;
7950
7951                 /* 2 reserved bytes */
7952                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7953                 offset += 2;
7954
7955                 /* security information */
7956                 offset = dissect_security_information_mask(tvb, tree, offset);
7957                 break;
7958         }
7959         case NT_TRANS_GET_USER_QUOTA:
7960                 /* not decoded yet */
7961                 break;
7962         case NT_TRANS_SET_USER_QUOTA:
7963                 /* not decoded yet */
7964                 break;
7965         }
7966
7967         return offset;
7968 }
7969
7970 static int
7971 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7972 {
7973         proto_item *item = NULL;
7974         proto_tree *tree = NULL;
7975         smb_info_t *si;
7976         int old_offset = offset;
7977
7978         si = (smb_info_t *)pinfo->private_data;
7979
7980         if(parent_tree){
7981                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7982                                 "%s Setup",
7983                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7984                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
7985         }
7986
7987         switch(ntd->subcmd){
7988         case NT_TRANS_CREATE:
7989                 break;
7990         case NT_TRANS_IOCTL: {
7991                 guint16 fid;
7992
7993                 /* function code */
7994                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
7995                 offset += 4;
7996
7997                 /* fid */
7998                 fid = tvb_get_letohs(tvb, offset);
7999                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8000                 offset += 2;
8001
8002                 /* isfsctl */
8003                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
8004                 offset += 1;
8005
8006                 /* isflags */
8007                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
8008
8009                 break;
8010         }
8011         case NT_TRANS_SSD:
8012                 break;
8013         case NT_TRANS_NOTIFY: {
8014                 guint16 fid;
8015
8016                 /* completion filter */
8017                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
8018
8019                 /* fid */
8020                 fid = tvb_get_letohs(tvb, offset);
8021                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8022                 offset += 2;
8023
8024                 /* watch tree */
8025                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
8026                 offset += 1;
8027
8028                 /* reserved byte */
8029                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8030                 offset += 1;
8031
8032                 break;
8033         }
8034         case NT_TRANS_RENAME:
8035                 /* XXX not documented */
8036                 break;
8037         case NT_TRANS_QSD:
8038                 break;
8039         case NT_TRANS_GET_USER_QUOTA:
8040                 /* not decoded yet */
8041                 break;
8042         case NT_TRANS_SET_USER_QUOTA:
8043                 /* not decoded yet */
8044                 break;
8045         }
8046
8047         return old_offset+len;
8048 }
8049
8050
8051 static int
8052 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8053 {
8054         guint8 wc, sc;
8055         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
8056         smb_info_t *si;
8057         smb_saved_info_t *sip;
8058         int subcmd;
8059         nt_trans_data ntd;
8060         guint16 bc;
8061         int padcnt;
8062         smb_nt_transact_info_t *nti;
8063
8064         si = (smb_info_t *)pinfo->private_data;
8065         sip = si->sip;
8066
8067         WORD_COUNT;
8068
8069         if(wc>=19){
8070                 /* primary request */
8071                 /* max setup count */
8072                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
8073                 offset += 1;
8074
8075                 /* 2 reserved bytes */
8076                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8077                 offset += 2;
8078         } else {
8079                 /* secondary request */
8080                 /* 3 reserved bytes */
8081                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8082                 offset += 3;
8083         }
8084
8085
8086         /* total param count */
8087         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
8088         offset += 4;
8089
8090         /* total data count */
8091         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
8092         offset += 4;
8093
8094         if(wc>=19){
8095                 /* primary request */
8096                 /* max param count */
8097                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
8098                 offset += 4;
8099
8100                 /* max data count */
8101                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
8102                 offset += 4;
8103         }
8104
8105         /* param count */
8106         pc = tvb_get_letohl(tvb, offset);
8107         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8108         offset += 4;
8109
8110         /* param offset */
8111         po = tvb_get_letohl(tvb, offset);
8112         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8113         offset += 4;
8114
8115         /* param displacement */
8116         if(wc>=19){
8117                 /* primary request*/
8118                 pd = 0;
8119         } else {
8120                 /* secondary request */
8121                 pd = tvb_get_letohl(tvb, offset);
8122                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8123                 offset += 4;
8124         }
8125
8126         /* data count */
8127         dc = tvb_get_letohl(tvb, offset);
8128         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8129         offset += 4;
8130
8131         /* data offset */
8132         od = tvb_get_letohl(tvb, offset);
8133         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8134         offset += 4;
8135
8136         /* data displacement */
8137         if(wc>=19){
8138                 /* primary request */
8139                 dd = 0;
8140         } else {
8141                 /* secondary request */
8142                 dd = tvb_get_letohl(tvb, offset);
8143                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8144                 offset += 4;
8145         }
8146
8147         /* setup count */
8148         if(wc>=19){
8149                 /* primary request */
8150                 sc = tvb_get_guint8(tvb, offset);
8151                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8152                 offset += 1;
8153         } else {
8154                 /* secondary request */
8155                 sc = 0;
8156         }
8157
8158         /* function */
8159         if(wc>=19){
8160                 /* primary request */
8161                 subcmd = tvb_get_letohs(tvb, offset);
8162                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
8163                 if(check_col(pinfo->cinfo, COL_INFO)){
8164                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8165                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
8166                 }
8167                 ntd.subcmd = subcmd;
8168                 if (!si->unidir) {
8169                         if(!pinfo->fd->flags.visited){
8170                                 /*
8171                                  * Allocate a new smb_nt_transact_info_t
8172                                  * structure.
8173                                  */
8174                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
8175                                 nti->subcmd = subcmd;
8176                                 sip->extra_info = nti;
8177                         }
8178                 }
8179         } else {
8180                 /* secondary request */
8181                 if(check_col(pinfo->cinfo, COL_INFO)){
8182                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
8183                 }
8184         }
8185         offset += 2;
8186
8187         /* this is a padding byte */
8188         if(offset%1){
8189                 /* pad byte */
8190                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
8191                 offset += 1;
8192         }
8193
8194         /* if there were any setup bytes, decode them */
8195         if(sc){
8196                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
8197                 offset += sc*2;
8198         }
8199
8200         BYTE_COUNT;
8201
8202         /* parameters */
8203         if(po>(guint32)offset){
8204                 /* We have some initial padding bytes.
8205                 */
8206                 padcnt = po-offset;
8207                 if (padcnt > bc)
8208                         padcnt = bc;
8209                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8210                 COUNT_BYTES(padcnt);
8211         }
8212         if(pc){
8213                 CHECK_BYTE_COUNT(pc);
8214                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
8215                 COUNT_BYTES(pc);
8216         }
8217
8218         /* data */
8219         if(od>(guint32)offset){
8220                 /* We have some initial padding bytes.
8221                 */
8222                 padcnt = od-offset;
8223                 if (padcnt > bc)
8224                         padcnt = bc;
8225                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8226                 COUNT_BYTES(padcnt);
8227         }
8228         if(dc){
8229                 CHECK_BYTE_COUNT(dc);
8230                 dissect_nt_trans_data_request(
8231                         tvb, pinfo, offset, tree, dc, &ntd);
8232                 COUNT_BYTES(dc);
8233         }
8234
8235         END_OF_SMB
8236
8237         return offset;
8238 }
8239
8240
8241
8242 static int
8243 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
8244                                int offset, proto_tree *parent_tree, int len,
8245                                nt_trans_data *ntd _U_)
8246 {
8247         proto_item *item = NULL;
8248         proto_tree *tree = NULL;
8249         smb_info_t *si;
8250         smb_nt_transact_info_t *nti;
8251         guint16 bcp;
8252
8253         si = (smb_info_t *)pinfo->private_data;
8254         if (si->sip != NULL)
8255                 nti = si->sip->extra_info;
8256         else
8257                 nti = NULL;
8258
8259         if(parent_tree){
8260                 if(nti != NULL){
8261                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8262                                 "%s Data",
8263                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8264                 } else {
8265                         /*
8266                          * We never saw the request to which this is a
8267                          * response.
8268                          */
8269                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8270                                 "Unknown NT Transaction Data (matching request not seen)");
8271                 }
8272                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8273         }
8274
8275         if (nti == NULL) {
8276                 offset += len;
8277                 return offset;
8278         }
8279         switch(nti->subcmd){
8280         case NT_TRANS_CREATE:
8281                 break;
8282         case NT_TRANS_IOCTL:
8283                 /* ioctl data */
8284                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
8285                 offset += len;
8286
8287                 break;
8288         case NT_TRANS_SSD:
8289                 break;
8290         case NT_TRANS_NOTIFY:
8291                 break;
8292         case NT_TRANS_RENAME:
8293                 /* XXX not documented */
8294                 break;
8295         case NT_TRANS_QSD: {
8296                 /*
8297                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
8298                  * which may be documented in the Win32 documentation
8299                  * somewhere.
8300                  */
8301                 offset = dissect_nt_sec_desc(
8302                         tvb, offset, pinfo, tree, NULL, len, NULL, NULL);
8303                 break;
8304         }
8305         case NT_TRANS_GET_USER_QUOTA:
8306                 bcp=len;
8307                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8308                 break;
8309         case NT_TRANS_SET_USER_QUOTA:
8310                 /* not decoded yet */
8311                 break;
8312         }
8313
8314         return offset;
8315 }
8316
8317 static int
8318 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
8319                                 int offset, proto_tree *parent_tree,
8320                                 int len, nt_trans_data *ntd _U_, guint16 bc)
8321 {
8322         proto_item *item = NULL;
8323         proto_tree *tree = NULL;
8324         guint32 fn_len;
8325         const char *fn;
8326         smb_info_t *si;
8327         smb_nt_transact_info_t *nti;
8328         guint16 fid;
8329         int old_offset;
8330         guint32 neo;
8331         int padcnt;
8332
8333         si = (smb_info_t *)pinfo->private_data;
8334         if (si->sip != NULL)
8335                 nti = si->sip->extra_info;
8336         else
8337                 nti = NULL;
8338
8339         if(parent_tree){
8340                 if(nti != NULL){
8341                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8342                                 "%s Parameters",
8343                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8344                 } else {
8345                         /*
8346                          * We never saw the request to which this is a
8347                          * response.
8348                          */
8349                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8350                                 "Unknown NT Transaction Parameters (matching request not seen)");
8351                 }
8352                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8353         }
8354
8355         if (nti == NULL) {
8356                 offset += len;
8357                 return offset;
8358         }
8359         switch(nti->subcmd){
8360         case NT_TRANS_CREATE:
8361                 /* oplock level */
8362                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8363                 offset += 1;
8364
8365                 /* reserved byte */
8366                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8367                 offset += 1;
8368
8369                 /* fid */
8370                 fid = tvb_get_letohs(tvb, offset);
8371                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8372                 offset += 2;
8373
8374                 /* create action */
8375                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8376                 offset += 4;
8377
8378                 /* ea error offset */
8379                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
8380                 offset += 4;
8381
8382                 /* create time */
8383                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8384                         hf_smb_create_time);
8385
8386                 /* access time */
8387                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8388                         hf_smb_access_time);
8389
8390                 /* last write time */
8391                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8392                         hf_smb_last_write_time);
8393
8394                 /* last change time */
8395                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8396                         hf_smb_change_time);
8397
8398                 /* Extended File Attributes */
8399                 offset = dissect_file_ext_attr(tvb, tree, offset);
8400
8401                 /* allocation size */
8402                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8403                 offset += 8;
8404
8405                 /* end of file */
8406                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8407                 offset += 8;
8408
8409                 /* File Type */
8410                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8411                 offset += 2;
8412
8413                 /* device state */
8414                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8415
8416                 /* is directory */
8417                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8418                 offset += 1;
8419                 break;
8420         case NT_TRANS_IOCTL:
8421                 break;
8422         case NT_TRANS_SSD:
8423                 break;
8424         case NT_TRANS_NOTIFY:
8425                 while(len){
8426                         old_offset = offset;
8427
8428                         /* next entry offset */
8429                         neo = tvb_get_letohl(tvb, offset);
8430                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8431                         COUNT_BYTES(4);
8432                         len -= 4;
8433                         /* broken implementations */
8434                         if(len<0)break;
8435
8436                         /* action */
8437                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
8438                         COUNT_BYTES(4);
8439                         len -= 4;
8440                         /* broken implementations */
8441                         if(len<0)break;
8442
8443                         /* file name len */
8444                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
8445                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8446                         COUNT_BYTES(4);
8447                         len -= 4;
8448                         /* broken implementations */
8449                         if(len<0)break;
8450
8451                         /* file name */
8452                         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8453                         if (fn == NULL)
8454                                 break;
8455                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8456                                 fn);
8457                         COUNT_BYTES(fn_len);
8458                         len -= fn_len;
8459                         /* broken implementations */
8460                         if(len<0)break;
8461
8462                         if (neo == 0)
8463                                 break;  /* no more structures */
8464
8465                         /* skip to next structure */
8466                         padcnt = (old_offset + neo) - offset;
8467                         if (padcnt < 0) {
8468                                 /*
8469                                  * XXX - this is bogus; flag it?
8470                                  */
8471                                 padcnt = 0;
8472                         }
8473                         if (padcnt != 0) {
8474                                 COUNT_BYTES(padcnt);
8475                                 len -= padcnt;
8476                                 /* broken implementations */
8477                                 if(len<0)break;
8478                         }
8479                 }
8480                 break;
8481         case NT_TRANS_RENAME:
8482                 /* XXX not documented */
8483                 break;
8484         case NT_TRANS_QSD:
8485                 /*
8486                  * This appears to be the size of the security
8487                  * descriptor; the calling sequence of
8488                  * "ZwQuerySecurityObject()" suggests that it would
8489                  * be.  The actual security descriptor wouldn't
8490                  * follow if the max data count in the request
8491                  * was smaller; this lets the client know how
8492                  * big a buffer it needs to provide.
8493                  */
8494                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
8495                 offset += 4;
8496                 break;
8497         case NT_TRANS_GET_USER_QUOTA:
8498                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
8499                         tvb_get_letohl(tvb, offset));
8500                 offset += 4;
8501                 break;
8502         case NT_TRANS_SET_USER_QUOTA:
8503                 /* not decoded yet */
8504                 break;
8505         }
8506
8507         return offset;
8508 }
8509
8510 static int
8511 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
8512                                 int offset, proto_tree *parent_tree,
8513                                 int len, nt_trans_data *ntd _U_)
8514 {
8515         proto_item *item = NULL;
8516         proto_tree *tree = NULL;
8517         smb_info_t *si;
8518         smb_nt_transact_info_t *nti;
8519
8520         si = (smb_info_t *)pinfo->private_data;
8521         if (si->sip != NULL)
8522                 nti = si->sip->extra_info;
8523         else
8524                 nti = NULL;
8525
8526         if(parent_tree){
8527                 if(nti != NULL){
8528                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8529                                 "%s Setup",
8530                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8531                 } else {
8532                         /*
8533                          * We never saw the request to which this is a
8534                          * response.
8535                          */
8536                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8537                                 "Unknown NT Transaction Setup (matching request not seen)");
8538                 }
8539                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8540         }
8541
8542         if (nti == NULL) {
8543                 offset += len;
8544                 return offset;
8545         }
8546         switch(nti->subcmd){
8547         case NT_TRANS_CREATE:
8548                 break;
8549         case NT_TRANS_IOCTL:
8550                 break;
8551         case NT_TRANS_SSD:
8552                 break;
8553         case NT_TRANS_NOTIFY:
8554                 break;
8555         case NT_TRANS_RENAME:
8556                 /* XXX not documented */
8557                 break;
8558         case NT_TRANS_QSD:
8559                 break;
8560         case NT_TRANS_GET_USER_QUOTA:
8561                 /* not decoded yet */
8562                 break;
8563         case NT_TRANS_SET_USER_QUOTA:
8564                 /* not decoded yet */
8565                 break;
8566         }
8567
8568         return offset;
8569 }
8570
8571 static int
8572 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8573 {
8574         guint8 wc, sc;
8575         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
8576         guint32 td=0, tp=0;
8577         smb_info_t *si;
8578         smb_nt_transact_info_t *nti;
8579         static nt_trans_data ntd;
8580         guint16 bc;
8581         int padcnt;
8582         fragment_data *r_fd = NULL;
8583         tvbuff_t *pd_tvb=NULL;
8584         gboolean save_fragmented;
8585
8586         si = (smb_info_t *)pinfo->private_data;
8587         if (si->sip != NULL)
8588                 nti = si->sip->extra_info;
8589         else
8590                 nti = NULL;
8591
8592         /* primary request */
8593         if(nti != NULL){
8594                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
8595                 if(check_col(pinfo->cinfo, COL_INFO)){
8596                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8597                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
8598                 }
8599         } else {
8600                 proto_tree_add_text(tree, tvb, offset, 0,
8601                         "Function: <unknown function - could not find matching request>");
8602                 if(check_col(pinfo->cinfo, COL_INFO)){
8603                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
8604                 }
8605         }
8606
8607         WORD_COUNT;
8608
8609         /* 3 reserved bytes */
8610         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8611         offset += 3;
8612
8613         /* total param count */
8614         tp = tvb_get_letohl(tvb, offset);
8615         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8616         offset += 4;
8617
8618         /* total data count */
8619         td = tvb_get_letohl(tvb, offset);
8620         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8621         offset += 4;
8622
8623         /* param count */
8624         pc = tvb_get_letohl(tvb, offset);
8625         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8626         offset += 4;
8627
8628         /* param offset */
8629         po = tvb_get_letohl(tvb, offset);
8630         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8631         offset += 4;
8632
8633         /* param displacement */
8634         pd = tvb_get_letohl(tvb, offset);
8635         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8636         offset += 4;
8637
8638         /* data count */
8639         dc = tvb_get_letohl(tvb, offset);
8640         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8641         offset += 4;
8642
8643         /* data offset */
8644         od = tvb_get_letohl(tvb, offset);
8645         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8646         offset += 4;
8647
8648         /* data displacement */
8649         dd = tvb_get_letohl(tvb, offset);
8650         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8651         offset += 4;
8652
8653         /* setup count */
8654         sc = tvb_get_guint8(tvb, offset);
8655         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8656         offset += 1;
8657
8658         /* setup data */
8659         if(sc){
8660                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
8661                 offset += sc*2;
8662         }
8663
8664         BYTE_COUNT;
8665
8666         /* reassembly of SMB NT Transaction data payload.
8667            In this section we do reassembly of both the data and parameters
8668            blocks of the SMB transaction command.
8669         */
8670         save_fragmented = pinfo->fragmented;
8671         /* do we need reassembly? */
8672         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
8673                 /* oh yeah, either data or parameter section needs
8674                    reassembly...
8675                 */
8676                 pinfo->fragmented = TRUE;
8677                 if(smb_trans_reassembly){
8678                         /* ...and we were told to do reassembly */
8679                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
8680                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8681                                                              po, pc, pd, td+tp);
8682
8683                         }
8684                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
8685                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8686                                                              od, dc, dd+tp, td+tp);
8687                         }
8688                 }
8689         }
8690
8691         /* if we got a reassembled fd structure from the reassembly routine we
8692            must create pd_tvb from it
8693         */
8694         if(r_fd){
8695                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
8696                                              r_fd->datalen);
8697                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
8698                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
8699
8700                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
8701         }
8702
8703
8704         if(pd_tvb){
8705           /* we have reassembled data, grab param and data from there */
8706           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
8707                                           &ntd, tvb_length(pd_tvb));
8708           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
8709         } else {
8710           /* we do not have reassembled data, just use what we have in the
8711              packet as well as we can */
8712           /* parameters */
8713           if(po>(guint32)offset){
8714             /* We have some initial padding bytes.
8715              */
8716             padcnt = po-offset;
8717             if (padcnt > bc)
8718               padcnt = bc;
8719             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8720             COUNT_BYTES(padcnt);
8721           }
8722           if(pc){
8723             CHECK_BYTE_COUNT(pc);
8724             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
8725             COUNT_BYTES(pc);
8726           }
8727
8728           /* data */
8729           if(od>(guint32)offset){
8730             /* We have some initial padding bytes.
8731              */
8732             padcnt = od-offset;
8733             if (padcnt > bc)
8734               padcnt = bc;
8735             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8736             COUNT_BYTES(padcnt);
8737           }
8738           if(dc){
8739             CHECK_BYTE_COUNT(dc);
8740             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
8741             COUNT_BYTES(dc);
8742           }
8743         }
8744         pinfo->fragmented = save_fragmented;
8745
8746         END_OF_SMB
8747
8748         return offset;
8749 }
8750
8751 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8752    NT Transaction command  ends here
8753    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8754
8755 static const value_string print_mode_vals[] = {
8756         {0,     "Text Mode"},
8757         {1,     "Graphics Mode"},
8758         {0, NULL}
8759 };
8760
8761 static int
8762 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8763 {
8764         smb_info_t *si = pinfo->private_data;
8765         int fn_len;
8766         const char *fn;
8767         guint8 wc;
8768         guint16 bc;
8769
8770         WORD_COUNT;
8771
8772         /* setup len */
8773         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
8774         offset += 2;
8775
8776         /* print mode */
8777         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
8778         offset += 2;
8779
8780         BYTE_COUNT;
8781
8782         /* buffer format */
8783         CHECK_BYTE_COUNT(1);
8784         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8785         COUNT_BYTES(1);
8786
8787         /* print identifier */
8788         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
8789         if (fn == NULL)
8790                 goto endofcommand;
8791         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
8792                 fn);
8793         COUNT_BYTES(fn_len);
8794
8795         END_OF_SMB
8796
8797         return offset;
8798 }
8799
8800
8801 static int
8802 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8803 {
8804         int cnt;
8805         guint8 wc;
8806         guint16 bc, fid;
8807
8808         WORD_COUNT;
8809
8810         /* fid */
8811         fid = tvb_get_letohs(tvb, offset);
8812         add_fid(tvb, pinfo, tree, offset, 2, fid);
8813         offset += 2;
8814
8815         BYTE_COUNT;
8816
8817         /* buffer format */
8818         CHECK_BYTE_COUNT(1);
8819         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8820         COUNT_BYTES(1);
8821
8822         /* data len */
8823         CHECK_BYTE_COUNT(2);
8824         cnt = tvb_get_letohs(tvb, offset);
8825         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
8826         COUNT_BYTES(2);
8827
8828         /* file data */
8829         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
8830
8831         END_OF_SMB
8832
8833         return offset;
8834 }
8835
8836
8837 static const value_string print_status_vals[] = {
8838         {1,     "Held or Stopped"},
8839         {2,     "Printing"},
8840         {3,     "Awaiting print"},
8841         {4,     "In intercept"},
8842         {5,     "File had error"},
8843         {6,     "Printer error"},
8844         {0, NULL}
8845 };
8846
8847 static int
8848 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8849 {
8850         guint8 wc;
8851         guint16 bc;
8852
8853         WORD_COUNT;
8854
8855         /* max count */
8856         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
8857         offset += 2;
8858
8859         /* start index */
8860         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
8861         offset += 2;
8862
8863         BYTE_COUNT;
8864
8865         END_OF_SMB
8866
8867         return offset;
8868 }
8869
8870 static int
8871 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
8872     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
8873 {
8874         proto_item *item = NULL;
8875         proto_tree *tree = NULL;
8876         smb_info_t *si = pinfo->private_data;
8877         int fn_len;
8878         const char *fn;
8879
8880         if(parent_tree){
8881                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
8882                         "Queue entry");
8883                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
8884         }
8885
8886         /* queued time */
8887         CHECK_BYTE_COUNT_SUBR(4);
8888         offset = dissect_smb_datetime(tvb, tree, offset,
8889                 hf_smb_print_queue_date,
8890                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
8891         *bcp -= 4;
8892
8893         /* status */
8894         CHECK_BYTE_COUNT_SUBR(1);
8895         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
8896         COUNT_BYTES_SUBR(1);
8897
8898         /* spool file number */
8899         CHECK_BYTE_COUNT_SUBR(2);
8900         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
8901         COUNT_BYTES_SUBR(2);
8902
8903         /* spool file size */
8904         CHECK_BYTE_COUNT_SUBR(4);
8905         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
8906         COUNT_BYTES_SUBR(4);
8907
8908         /* reserved byte */
8909         CHECK_BYTE_COUNT_SUBR(1);
8910         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8911         COUNT_BYTES_SUBR(1);
8912
8913         /* file name */
8914         fn_len = 16;
8915         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
8916         CHECK_STRING_SUBR(fn);
8917         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
8918                 fn);
8919         COUNT_BYTES_SUBR(fn_len);
8920
8921         *trunc = FALSE;
8922         return offset;
8923 }
8924
8925 static int
8926 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8927 {
8928         guint16 cnt=0, len;
8929         guint8 wc;
8930         guint16 bc;
8931         gboolean trunc;
8932
8933         WORD_COUNT;
8934
8935         /* count */
8936         cnt = tvb_get_letohs(tvb, offset);
8937         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
8938         offset += 2;
8939
8940         /* restart index */
8941         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
8942         offset += 2;
8943
8944         BYTE_COUNT;
8945
8946         /* buffer format */
8947         CHECK_BYTE_COUNT(1);
8948         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8949         COUNT_BYTES(1);
8950
8951         /* data len */
8952         CHECK_BYTE_COUNT(2);
8953         len = tvb_get_letohs(tvb, offset);
8954         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
8955         COUNT_BYTES(2);
8956
8957         /* queue elements */
8958         while(cnt--){
8959                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
8960                     &bc, &trunc);
8961                 if (trunc)
8962                         goto endofcommand;
8963         }
8964
8965         END_OF_SMB
8966
8967         return offset;
8968 }
8969
8970
8971 static int
8972 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8973 {
8974         int name_len;
8975         guint16 bc;
8976         guint8 wc;
8977         guint16 message_len;
8978
8979         WORD_COUNT;
8980
8981         BYTE_COUNT;
8982
8983         /* buffer format */
8984         CHECK_BYTE_COUNT(1);
8985         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8986         COUNT_BYTES(1);
8987
8988         /* originator name */
8989         /* XXX - what if this runs past bc? */
8990         name_len = tvb_strsize(tvb, offset);
8991         CHECK_BYTE_COUNT(name_len);
8992         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
8993             name_len, TRUE);
8994         COUNT_BYTES(name_len);
8995
8996         /* buffer format */
8997         CHECK_BYTE_COUNT(1);
8998         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8999         COUNT_BYTES(1);
9000
9001         /* destination name */
9002         /* XXX - what if this runs past bc? */
9003         name_len = tvb_strsize(tvb, offset);
9004         CHECK_BYTE_COUNT(name_len);
9005         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9006             name_len, TRUE);
9007         COUNT_BYTES(name_len);
9008
9009         /* buffer format */
9010         CHECK_BYTE_COUNT(1);
9011         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9012         COUNT_BYTES(1);
9013
9014         /* message len */
9015         CHECK_BYTE_COUNT(2);
9016         message_len = tvb_get_letohs(tvb, offset);
9017         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9018             message_len);
9019         COUNT_BYTES(2);
9020
9021         /* message */
9022         CHECK_BYTE_COUNT(message_len);
9023         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9024             TRUE);
9025         COUNT_BYTES(message_len);
9026
9027         END_OF_SMB
9028
9029         return offset;
9030 }
9031
9032 static int
9033 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9034 {
9035         int name_len;
9036         guint16 bc;
9037         guint8 wc;
9038
9039         WORD_COUNT;
9040
9041         BYTE_COUNT;
9042
9043         /* buffer format */
9044         CHECK_BYTE_COUNT(1);
9045         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9046         COUNT_BYTES(1);
9047
9048         /* originator name */
9049         /* XXX - what if this runs past bc? */
9050         name_len = tvb_strsize(tvb, offset);
9051         CHECK_BYTE_COUNT(name_len);
9052         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9053             name_len, TRUE);
9054         COUNT_BYTES(name_len);
9055
9056         /* buffer format */
9057         CHECK_BYTE_COUNT(1);
9058         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9059         COUNT_BYTES(1);
9060
9061         /* destination name */
9062         /* XXX - what if this runs past bc? */
9063         name_len = tvb_strsize(tvb, offset);
9064         CHECK_BYTE_COUNT(name_len);
9065         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9066             name_len, TRUE);
9067         COUNT_BYTES(name_len);
9068
9069         END_OF_SMB
9070
9071         return offset;
9072 }
9073
9074 static int
9075 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9076 {
9077         guint16 bc;
9078         guint8 wc;
9079
9080         WORD_COUNT;
9081
9082         /* message group ID */
9083         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
9084         offset += 2;
9085
9086         BYTE_COUNT;
9087
9088         END_OF_SMB
9089
9090         return offset;
9091 }
9092
9093 static int
9094 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9095 {
9096         guint16 bc;
9097         guint8 wc;
9098         guint16 message_len;
9099
9100         WORD_COUNT;
9101
9102         BYTE_COUNT;
9103
9104         /* buffer format */
9105         CHECK_BYTE_COUNT(1);
9106         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9107         COUNT_BYTES(1);
9108
9109         /* message len */
9110         CHECK_BYTE_COUNT(2);
9111         message_len = tvb_get_letohs(tvb, offset);
9112         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9113             message_len);
9114         COUNT_BYTES(2);
9115
9116         /* message */
9117         CHECK_BYTE_COUNT(message_len);
9118         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9119             TRUE);
9120         COUNT_BYTES(message_len);
9121
9122         END_OF_SMB
9123
9124         return offset;
9125 }
9126
9127 static int
9128 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9129 {
9130         int name_len;
9131         guint16 bc;
9132         guint8 wc;
9133
9134         WORD_COUNT;
9135
9136         BYTE_COUNT;
9137
9138         /* buffer format */
9139         CHECK_BYTE_COUNT(1);
9140         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9141         COUNT_BYTES(1);
9142
9143         /* forwarded name */
9144         /* XXX - what if this runs past bc? */
9145         name_len = tvb_strsize(tvb, offset);
9146         CHECK_BYTE_COUNT(name_len);
9147         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
9148             name_len, TRUE);
9149         COUNT_BYTES(name_len);
9150
9151         END_OF_SMB
9152
9153         return offset;
9154 }
9155
9156 static int
9157 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9158 {
9159         int name_len;
9160         guint16 bc;
9161         guint8 wc;
9162
9163         WORD_COUNT;
9164
9165         BYTE_COUNT;
9166
9167         /* buffer format */
9168         CHECK_BYTE_COUNT(1);
9169         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9170         COUNT_BYTES(1);
9171
9172         /* machine name */
9173         /* XXX - what if this runs past bc? */
9174         name_len = tvb_strsize(tvb, offset);
9175         CHECK_BYTE_COUNT(name_len);
9176         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
9177             name_len, TRUE);
9178         COUNT_BYTES(name_len);
9179
9180         END_OF_SMB
9181
9182         return offset;
9183 }
9184
9185
9186 static int
9187 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9188 {
9189         guint8  wc, cmd=0xff;
9190         guint16 andxoffset=0;
9191         guint16 bc;
9192         smb_info_t *si = pinfo->private_data;
9193         int fn_len;
9194         const char *fn;
9195
9196         WORD_COUNT;
9197
9198         /* next smb command */
9199         cmd = tvb_get_guint8(tvb, offset);
9200         if(cmd!=0xff){
9201                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9202         } else {
9203                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
9204         }
9205         offset += 1;
9206
9207         /* reserved byte */
9208         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9209         offset += 1;
9210
9211         /* andxoffset */
9212         andxoffset = tvb_get_letohs(tvb, offset);
9213         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9214         offset += 2;
9215
9216         /* reserved byte */
9217         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9218         offset += 1;
9219
9220         /* file name len */
9221         fn_len = tvb_get_letohs(tvb, offset);
9222         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
9223         offset += 2;
9224
9225         /* Create flags */
9226         offset = dissect_nt_create_bits(tvb, tree, offset);
9227
9228         /* root directory fid */
9229         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
9230         offset += 4;
9231
9232         /* nt access mask */
9233         offset = dissect_smb_access_mask(tvb, tree, offset);
9234
9235         /* allocation size */
9236         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9237         offset += 8;
9238
9239         /* Extended File Attributes */
9240         offset = dissect_file_ext_attr(tvb, tree, offset);
9241
9242         /* share access */
9243         offset = dissect_nt_share_access(tvb, tree, offset);
9244
9245         /* create disposition */
9246         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
9247         offset += 4;
9248
9249         /* create options */
9250         offset = dissect_nt_create_options(tvb, tree, offset);
9251
9252         /* impersonation level */
9253         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
9254         offset += 4;
9255
9256         /* security flags */
9257         offset = dissect_nt_security_flags(tvb, tree, offset);
9258
9259         BYTE_COUNT;
9260
9261         /* file name */
9262         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9263         if (fn == NULL)
9264                 goto endofcommand;
9265         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9266                 fn);
9267         COUNT_BYTES(fn_len);
9268
9269         if (check_col(pinfo->cinfo, COL_INFO)) {
9270                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
9271         }
9272
9273         END_OF_SMB
9274
9275         /* call AndXCommand (if there are any) */
9276         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9277
9278         return offset;
9279 }
9280
9281
9282 static int
9283 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9284 {
9285         guint8  wc, cmd=0xff;
9286         guint16 andxoffset=0;
9287         guint16 bc;
9288         guint16 fid;
9289
9290         WORD_COUNT;
9291
9292         /* next smb command */
9293         cmd = tvb_get_guint8(tvb, offset);
9294         if(cmd!=0xff){
9295                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9296         } else {
9297                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
9298         }
9299         offset += 1;
9300
9301         /* reserved byte */
9302         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9303         offset += 1;
9304
9305         /* andxoffset */
9306         andxoffset = tvb_get_letohs(tvb, offset);
9307         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9308         offset += 2;
9309
9310         /* oplock level */
9311         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
9312         offset += 1;
9313
9314         /* fid */
9315         fid = tvb_get_letohs(tvb, offset);
9316         add_fid(tvb, pinfo, tree, offset, 2, fid);
9317         offset += 2;
9318
9319         /* create action */
9320         /*XXX is this really the same as create disposition in the request? it looks so*/
9321         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
9322         offset += 4;
9323
9324         /* create time */
9325         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
9326
9327         /* access time */
9328         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
9329
9330         /* last write time */
9331         offset = dissect_smb_64bit_time(tvb, tree, offset,
9332                 hf_smb_last_write_time);
9333
9334         /* last change time */
9335         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
9336
9337         /* Extended File Attributes */
9338         offset = dissect_file_ext_attr(tvb, tree, offset);
9339
9340         /* allocation size */
9341         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9342         offset += 8;
9343
9344         /* end of file */
9345         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9346         offset += 8;
9347
9348         /* File Type */
9349         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
9350         offset += 2;
9351
9352         /* IPC State */
9353         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9354
9355         /* is directory */
9356         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9357         offset += 1;
9358
9359         BYTE_COUNT;
9360
9361         END_OF_SMB
9362
9363         /* call AndXCommand (if there are any) */
9364         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9365
9366         return offset;
9367 }
9368
9369
9370 static int
9371 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9372 {
9373         guint8 wc;
9374         guint16 bc;
9375
9376         WORD_COUNT;
9377
9378         BYTE_COUNT;
9379
9380         END_OF_SMB
9381
9382         return offset;
9383 }
9384
9385 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9386    BEGIN Transaction/Transaction2 Primary and secondary requests
9387    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9388
9389
9390 const value_string trans2_cmd_vals[] = {
9391         { 0x00,         "OPEN2" },
9392         { 0x01,         "FIND_FIRST2" },
9393         { 0x02,         "FIND_NEXT2" },
9394         { 0x03,         "QUERY_FS_INFORMATION" },
9395         { 0x04,         "SET_FS_QUOTA" },
9396         { 0x05,         "QUERY_PATH_INFORMATION" },
9397         { 0x06,         "SET_PATH_INFORMATION" },
9398         { 0x07,         "QUERY_FILE_INFORMATION" },
9399         { 0x08,         "SET_FILE_INFORMATION" },
9400         { 0x09,         "FSCTL" },
9401         { 0x0A,         "IOCTL2" },
9402         { 0x0B,         "FIND_NOTIFY_FIRST" },
9403         { 0x0C,         "FIND_NOTIFY_NEXT" },
9404         { 0x0D,         "CREATE_DIRECTORY" },
9405         { 0x0E,         "SESSION_SETUP" },
9406         { 0x10,         "GET_DFS_REFERRAL" },
9407         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
9408         { 0,    NULL }
9409 };
9410
9411 static const true_false_string tfs_tf_dtid = {
9412         "Also DISCONNECT TID",
9413         "Do NOT disconnect TID"
9414 };
9415 static const true_false_string tfs_tf_owt = {
9416         "One Way Transaction (NO RESPONSE)",
9417         "Two way transaction"
9418 };
9419
9420 static const true_false_string tfs_ff2_backup = {
9421         "Find WITH backup intent",
9422         "No backup intent"
9423 };
9424 static const true_false_string tfs_ff2_continue = {
9425         "CONTINUE search from previous position",
9426         "New search, do NOT continue from previous position"
9427 };
9428 static const true_false_string tfs_ff2_resume = {
9429         "Return RESUME keys",
9430         "Do NOT return resume keys"
9431 };
9432 static const true_false_string tfs_ff2_close_eos = {
9433         "CLOSE search if END OF SEARCH is reached",
9434         "Do NOT close search if end of search reached"
9435 };
9436 static const true_false_string tfs_ff2_close = {
9437         "CLOSE search after this request",
9438         "Do NOT close search after this request"
9439 };
9440
9441 /* used by
9442    TRANS2_FIND_FIRST2
9443 */
9444 static const value_string ff2_il_vals[] = {
9445         { 1,            "Info Standard  (4.3.4.1)"},
9446         { 2,            "Info Query EA Size  (4.3.4.2)"},
9447         { 3,            "Info Query EAs From List  (4.3.4.2)"},
9448         { 0x0101,       "Find File Directory Info  (4.3.4.4)"},
9449         { 0x0102,       "Find File Full Directory Info  (4.3.4.5)"},
9450         { 0x0103,       "Find File Names Info  (4.3.4.7)"},
9451         { 0x0104,       "Find File Both Directory Info  (4.3.4.6)"},
9452         { 0x0202,       "Find File UNIX  (4.3.4.8)"},
9453         {0, NULL}
9454 };
9455
9456 /* values used by :
9457         TRANS2_QUERY_PATH_INFORMATION
9458         TRANS2_SET_PATH_INFORMATION
9459 */
9460 static const value_string qpi_loi_vals[] = {
9461         { 1,            "Info Standard  (4.2.14.1)"},
9462         { 2,            "Info Query EA Size  (4.2.14.1)"},
9463         { 3,            "Info Query EAs From List  (4.2.14.2)"},
9464         { 4,            "Info Query All EAs  (4.2.14.2)"},
9465         { 6,            "Info Is Name Valid  (4.2.14.3)"},
9466         { 0x0101,       "Query File Basic Info  (4.2.14.4)"},
9467         { 0x0102,       "Query File Standard Info  (4.2.14.5)"},
9468         { 0x0103,       "Query File EA Info  (4.2.14.6)"},
9469         { 0x0104,       "Query File Name Info  (4.2.14.7)"},
9470         { 0x0107,       "Query File All Info  (4.2.14.8)"},
9471         { 0x0108,       "Query File Alt Name Info  (4.2.14.7)"},
9472         { 0x0109,       "Query File Stream Info  (4.2.14.10)"},
9473         { 0x010b,       "Query File Compression Info  (4.2.14.11)"},
9474         { 0x0200,       "Set File Unix Basic"},
9475         { 0x0201,       "Set File Unix Link"},
9476         { 0x0202,       "Set File Unix HardLink"},
9477         { 1004,         "Query File Basic Info  (4.2.14.4)"},
9478         { 1005,         "Query File Standard Info  (4.2.14.5)"},
9479         { 1006,         "Query File Internal Info  (4.2.14.?)"},
9480         { 1007,         "Query File EA Info  (4.2.14.6)"},
9481         { 1009,         "Query File Name Info  (4.2.14.7)"},
9482         { 1010,         "Query File Rename Info  (4.2.14.?)"},
9483         { 1011,         "Query File Link Info  (4.2.14.?)"},
9484         { 1012,         "Query File Names Info  (4.2.14.?)"},
9485         { 1013,         "Query File Disposition Info  (4.2.14.?)"},
9486         { 1014,         "Query File Position Info  (4.2.14.?)"},
9487         { 1015,         "Query File Full EA Info  (4.2.14.?)"},
9488         { 1016,         "Query File Mode Info  (4.2.14.?)"},
9489         { 1017,         "Query File Alignment Info  (4.2.14.?)"},
9490         { 1018,         "Query File All Info  (4.2.14.8)"},
9491         { 1019,         "Query File Allocation Info  (4.2.14.?)"},
9492         { 1020,         "Query File End of File Info  (4.2.14.?)"},
9493         { 1021,         "Query File Alt Name Info  (4.2.14.7)"},
9494         { 1022,         "Query File Stream Info  (4.2.14.10)"},
9495         { 1023,         "Query File Pipe Info  (4.2.14.?)"},
9496         { 1024,         "Query File Pipe Local Info  (4.2.14.?)"},
9497         { 1025,         "Query File Pipe Remote Info  (4.2.14.?)"},
9498         { 1026,         "Query File Mailslot Query Info  (4.2.14.?)"},
9499         { 1027,         "Query File Mailslot Set Info  (4.2.14.?)"},
9500         { 1028,         "Query File Compression Info  (4.2.14.11)"},
9501         { 1029,         "Query File ObjectID Info  (4.2.14.?)"},
9502         { 1030,         "Query File Completion Info  (4.2.14.?)"},
9503         { 1031,         "Query File Move Cluster Info  (4.2.14.?)"},
9504         { 1032,         "Query File Quota Info  (4.2.14.?)"},
9505         { 1033,         "Query File Reparsepoint Info  (4.2.14.?)"},
9506         { 1034,         "Query File Network Open Info  (4.2.14.?)"},
9507         { 1035,         "Query File Attribute Tag Info  (4.2.14.?)"},
9508         { 1036,         "Query File Tracking Info  (4.2.14.?)"},
9509         { 1037,         "Query File Maximum Info  (4.2.14.?)"},
9510         {0, NULL}
9511 };
9512
9513 static const value_string qfsi_vals[] = {
9514         { 1,            "Info Allocation"},
9515         { 2,            "Info Volume"},
9516         { 0x0101,       "Query FS Label Info"},
9517         { 0x0102,       "Query FS Volume Info"},
9518         { 0x0103,       "Query FS Size Info"},
9519         { 0x0104,       "Query FS Device Info"},
9520         { 0x0105,       "Query FS Attribute Info"},
9521         { 0x0301,       "Mac Query FS INFO"},
9522         { 1001,         "Query FS Label Info"},
9523         { 1002,         "Query FS Volume Info"},
9524         { 1003,         "Query FS Size Info"},
9525         { 1004,         "Query FS Device Info"},
9526         { 1005,         "Query FS Attribute Info"},
9527         { 1006,         "Query FS Quota Info"},
9528         { 1007,         "Query Full FS Size Info"},
9529         {0, NULL}
9530 };
9531
9532 static const value_string nt_rename_vals[] = {
9533         { 0x0103,       "Create Hard Link"},
9534         {0, NULL}
9535 };
9536
9537
9538 static const value_string delete_pending_vals[] = {
9539         {0,     "Normal, no pending delete"},
9540         {1,     "This object has DELETE PENDING"},
9541         {0, NULL}
9542 };
9543
9544 static const value_string alignment_vals[] = {
9545         {0,     "Byte alignment"},
9546         {1,     "Word (16bit) alignment"},
9547         {3,     "Long (32bit) alignment"},
9548         {7,     "8 byte boundary alignment"},
9549         {0x0f,  "16 byte boundary alignment"},
9550         {0x1f,  "32 byte boundary alignment"},
9551         {0x3f,  "64 byte boundary alignment"},
9552         {0x7f,  "128 byte boundary alignment"},
9553         {0xff,  "256 byte boundary alignment"},
9554         {0x1ff, "512 byte boundary alignment"},
9555         {0, NULL}
9556 };
9557
9558
9559 static const true_false_string tfs_get_dfs_server_hold_storage = {
9560         "Referral SERVER HOLDS STORAGE for the file",
9561         "Referral server does NOT hold storage for the file"
9562 };
9563 static const true_false_string tfs_get_dfs_fielding = {
9564         "The server in referral is FIELDING CAPABLE",
9565         "The server in referrals is NOT fielding capable"
9566 };
9567
9568 static const true_false_string tfs_dfs_referral_flags_strip = {
9569         "STRIP off pathconsumed characters before submitting",
9570         "Do NOT strip off any characters"
9571 };
9572
9573 static const value_string dfs_referral_server_type_vals[] = {
9574         {0,     "Don't know"},
9575         {1,     "SMB Server"},
9576         {2,     "Netware Server"},
9577         {3,     "Domain Server"},
9578         {0, NULL}
9579 };
9580
9581
9582 static const true_false_string tfs_device_char_removable = {
9583         "This is a REMOVABLE device",
9584         "This is NOT a removable device"
9585 };
9586 static const true_false_string tfs_device_char_read_only = {
9587         "This is a READ-ONLY device",
9588         "This is NOT a read-only device"
9589 };
9590 static const true_false_string tfs_device_char_floppy = {
9591         "This is a FLOPPY DISK device",
9592         "This is NOT a floppy disk device"
9593 };
9594 static const true_false_string tfs_device_char_write_once = {
9595         "This is a WRITE-ONCE device",
9596         "This is NOT a write-once device"
9597 };
9598 static const true_false_string tfs_device_char_remote = {
9599         "This is a REMOTE device",
9600         "This is NOT a remote device"
9601 };
9602 static const true_false_string tfs_device_char_mounted = {
9603         "This device is MOUNTED",
9604         "This device is NOT mounted"
9605 };
9606 static const true_false_string tfs_device_char_virtual = {
9607         "This is a VIRTUAL device",
9608         "This is NOT a virtual device"
9609 };
9610
9611
9612 static const true_false_string tfs_fs_attr_css = {
9613         "This FS supports CASE SENSITIVE SEARCHes",
9614         "This FS does NOT support case sensitive searches"
9615 };
9616 static const true_false_string tfs_fs_attr_cpn = {
9617         "This FS supports CASE PRESERVED NAMES",
9618         "This FS does NOT support case preserved names"
9619 };
9620 static const true_false_string tfs_fs_attr_pacls = {
9621         "This FS supports PERSISTENT ACLs",
9622         "This FS does NOT support persistent acls"
9623 };
9624 static const true_false_string tfs_fs_attr_fc = {
9625         "This FS supports COMPRESSED FILES",
9626         "This FS does NOT support compressed files"
9627 };
9628 static const true_false_string tfs_fs_attr_vq = {
9629         "This FS supports VOLUME QUOTAS",
9630         "This FS does NOT support volume quotas"
9631 };
9632 static const true_false_string tfs_fs_attr_dim = {
9633         "This FS is on a MOUNTED DEVICE",
9634         "This FS is NOT on a mounted device"
9635 };
9636 static const true_false_string tfs_fs_attr_vic = {
9637         "This FS is on a COMPRESSED VOLUME",
9638         "This FS is NOT on a compressed volume"
9639 };
9640
9641 #define FF2_RESUME      0x0004
9642
9643 static int
9644 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9645 {
9646         guint16 mask;
9647         proto_item *item = NULL;
9648         proto_tree *tree = NULL;
9649         smb_info_t *si;
9650         smb_transact2_info_t *t2i;
9651
9652         mask = tvb_get_letohs(tvb, offset);
9653
9654         si = (smb_info_t *)pinfo->private_data;
9655         if (si->sip != NULL) {
9656                 t2i = si->sip->extra_info;
9657                 if (t2i != NULL) {
9658                         if (!pinfo->fd->flags.visited)
9659                                 t2i->resume_keys = (mask & FF2_RESUME);
9660                 }
9661         }
9662
9663         if(parent_tree){
9664                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9665                         "Flags: 0x%04x", mask);
9666                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
9667         }
9668
9669         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
9670                 tvb, offset, 2, mask);
9671         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
9672                 tvb, offset, 2, mask);
9673         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
9674                 tvb, offset, 2, mask);
9675         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
9676                 tvb, offset, 2, mask);
9677         proto_tree_add_boolean(tree, hf_smb_ff2_close,
9678                 tvb, offset, 2, mask);
9679
9680         offset += 2;
9681
9682         return offset;
9683 }
9684
9685 #if 0
9686 static int
9687 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9688 {
9689         guint16 mask;
9690         proto_item *item = NULL;
9691         proto_tree *tree = NULL;
9692
9693         mask = tvb_get_letohs(tvb, offset);
9694
9695         if(parent_tree){
9696                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9697                         "IO Flag: 0x%04x", mask);
9698                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
9699         }
9700
9701         proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
9702                 tvb, offset, 2, mask);
9703         proto_tree_add_boolean(tree, hf_smb_sfi_caching,
9704                 tvb, offset, 2, mask);
9705
9706         offset += 2;
9707
9708         return offset;
9709 }
9710 #endif
9711
9712 static int
9713 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
9714     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
9715 {
9716         proto_item *item = NULL;
9717         proto_tree *tree = NULL;
9718         smb_info_t *si;
9719         smb_transact2_info_t *t2i;
9720         int fn_len;
9721         const char *fn;
9722         int old_offset = offset;
9723
9724         si = (smb_info_t *)pinfo->private_data;
9725         if (si->sip != NULL)
9726                 t2i = si->sip->extra_info;
9727         else
9728                 t2i = NULL;
9729
9730         if(parent_tree){
9731                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
9732                                 "%s Parameters",
9733                                 val_to_str(subcmd, trans2_cmd_vals,
9734                                            "Unknown (0x%02x)"));
9735                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
9736         }
9737
9738         switch(subcmd){
9739         case 0x00:      /*TRANS2_OPEN2*/
9740                 /* open flags */
9741                 CHECK_BYTE_COUNT_TRANS(2);
9742                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
9743                 bc -= 2;
9744
9745                 /* desired access */
9746                 CHECK_BYTE_COUNT_TRANS(2);
9747                 offset = dissect_access(tvb, tree, offset, "Desired");
9748                 bc -= 2;
9749
9750                 /* Search Attributes */
9751                 CHECK_BYTE_COUNT_TRANS(2);
9752                 offset = dissect_search_attributes(tvb, tree, offset);
9753                 bc -= 2;
9754
9755                 /* File Attributes */
9756                 CHECK_BYTE_COUNT_TRANS(2);
9757                 offset = dissect_file_attributes(tvb, tree, offset, 2);
9758                 bc -= 2;
9759
9760                 /* create time */
9761                 CHECK_BYTE_COUNT_TRANS(4);
9762                 offset = dissect_smb_datetime(tvb, tree, offset,
9763                         hf_smb_create_time,
9764                         hf_smb_create_dos_date, hf_smb_create_dos_time,
9765                         TRUE);
9766                 bc -= 4;
9767
9768                 /* open function */
9769                 CHECK_BYTE_COUNT_TRANS(2);
9770                 offset = dissect_open_function(tvb, tree, offset);
9771                 bc -= 2;
9772
9773                 /* allocation size */
9774                 CHECK_BYTE_COUNT_TRANS(4);
9775                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
9776                 COUNT_BYTES_TRANS(4);
9777
9778                 /* 10 reserved bytes */
9779                 CHECK_BYTE_COUNT_TRANS(10);
9780                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
9781                 COUNT_BYTES_TRANS(10);
9782
9783                 /* file name */
9784                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9785                 CHECK_STRING_TRANS(fn);
9786                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9787                         fn);
9788                 COUNT_BYTES_TRANS(fn_len);
9789
9790                 if (check_col(pinfo->cinfo, COL_INFO)) {
9791                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9792                         fn);
9793                 }
9794                 break;
9795         case 0x01:      /*TRANS2_FIND_FIRST2*/
9796                 /* Search Attributes */
9797                 CHECK_BYTE_COUNT_TRANS(2);
9798                 offset = dissect_search_attributes(tvb, tree, offset);
9799                 bc -= 2;
9800
9801                 /* search count */
9802                 CHECK_BYTE_COUNT_TRANS(2);
9803                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
9804                 COUNT_BYTES_TRANS(2);
9805
9806                 /* Find First2 flags */
9807                 CHECK_BYTE_COUNT_TRANS(2);
9808                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
9809                 bc -= 2;
9810
9811                 /* Find First2 information level */
9812                 CHECK_BYTE_COUNT_TRANS(2);
9813                 si->info_level = tvb_get_letohs(tvb, offset);
9814                 if (!pinfo->fd->flags.visited)
9815                         t2i->info_level = si->info_level;
9816                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
9817                 COUNT_BYTES_TRANS(2);
9818
9819                 /* storage type */
9820                 CHECK_BYTE_COUNT_TRANS(4);
9821                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
9822                 COUNT_BYTES_TRANS(4);
9823
9824                 /* search pattern */
9825                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9826                 CHECK_STRING_TRANS(fn);
9827                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
9828                         fn);
9829                 COUNT_BYTES_TRANS(fn_len);
9830
9831                 if (check_col(pinfo->cinfo, COL_INFO)) {
9832                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
9833                         fn);
9834                 }
9835
9836                 break;
9837         case 0x02:      /*TRANS2_FIND_NEXT2*/
9838                 /* sid */
9839                 CHECK_BYTE_COUNT_TRANS(2);
9840                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
9841                 COUNT_BYTES_TRANS(2);
9842
9843                 /* search count */
9844                 CHECK_BYTE_COUNT_TRANS(2);
9845                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
9846                 COUNT_BYTES_TRANS(2);
9847
9848                 /* Find First2 information level */
9849                 CHECK_BYTE_COUNT_TRANS(2);
9850                 si->info_level = tvb_get_letohs(tvb, offset);
9851                 if (!pinfo->fd->flags.visited)
9852                         t2i->info_level = si->info_level;
9853                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
9854                 COUNT_BYTES_TRANS(2);
9855
9856                 /* resume key */
9857                 CHECK_BYTE_COUNT_TRANS(4);
9858                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
9859                 COUNT_BYTES_TRANS(4);
9860
9861                 /* Find First2 flags */
9862                 CHECK_BYTE_COUNT_TRANS(2);
9863                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
9864                 bc -= 2;
9865
9866                 /* file name */
9867                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9868                 CHECK_STRING_TRANS(fn);
9869                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9870                         fn);
9871                 COUNT_BYTES_TRANS(fn_len);
9872
9873                 if (check_col(pinfo->cinfo, COL_INFO)) {
9874                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
9875                         fn);
9876                 }
9877
9878                 break;
9879         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
9880                 /* level of interest */
9881                 CHECK_BYTE_COUNT_TRANS(2);
9882                 si->info_level = tvb_get_letohs(tvb, offset);
9883                 if (!pinfo->fd->flags.visited)
9884                         t2i->info_level = si->info_level;
9885                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
9886                 COUNT_BYTES_TRANS(2);
9887
9888                 break;
9889         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
9890                 /* level of interest */
9891                 CHECK_BYTE_COUNT_TRANS(2);
9892                 si->info_level = tvb_get_letohs(tvb, offset);
9893                 if (!pinfo->fd->flags.visited)
9894                         t2i->info_level = si->info_level;
9895                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9896                 COUNT_BYTES_TRANS(2);
9897
9898                 /* 4 reserved bytes */
9899                 CHECK_BYTE_COUNT_TRANS(4);
9900                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9901                 COUNT_BYTES_TRANS(4);
9902
9903                 /* file name */
9904                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9905                 CHECK_STRING_TRANS(fn);
9906                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9907                         fn);
9908                 COUNT_BYTES_TRANS(fn_len);
9909
9910                 if (check_col(pinfo->cinfo, COL_INFO)) {
9911                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9912                         fn);
9913                 }
9914
9915                 break;
9916         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
9917                 /* level of interest */
9918                 CHECK_BYTE_COUNT_TRANS(2);
9919                 si->info_level = tvb_get_letohs(tvb, offset);
9920                 if (!pinfo->fd->flags.visited)
9921                         t2i->info_level = si->info_level;
9922                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9923                 COUNT_BYTES_TRANS(2);
9924
9925                 /* 4 reserved bytes */
9926                 CHECK_BYTE_COUNT_TRANS(4);
9927                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9928                 COUNT_BYTES_TRANS(4);
9929
9930                 /* file name */
9931                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9932                 CHECK_STRING_TRANS(fn);
9933                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9934                         fn);
9935                 COUNT_BYTES_TRANS(fn_len);
9936
9937                 if (check_col(pinfo->cinfo, COL_INFO)) {
9938                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9939                         fn);
9940                 }
9941
9942                 break;
9943         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
9944                 guint16 fid;
9945
9946                 /* fid */
9947                 CHECK_BYTE_COUNT_TRANS(2);
9948                 fid = tvb_get_letohs(tvb, offset);
9949                 add_fid(tvb, pinfo, tree, offset, 2, fid);
9950                 COUNT_BYTES_TRANS(2);
9951
9952                 /* level of interest */
9953                 CHECK_BYTE_COUNT_TRANS(2);
9954                 si->info_level = tvb_get_letohs(tvb, offset);
9955                 if (!pinfo->fd->flags.visited)
9956                         t2i->info_level = si->info_level;
9957                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9958                 COUNT_BYTES_TRANS(2);
9959
9960                 break;
9961         }
9962         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
9963                 guint16 fid;
9964
9965                 /* fid */
9966                 CHECK_BYTE_COUNT_TRANS(2);
9967                 fid = tvb_get_letohs(tvb, offset);
9968                 add_fid(tvb, pinfo, tree, offset, 2, fid);
9969                 COUNT_BYTES_TRANS(2);
9970
9971                 /* level of interest */
9972                 CHECK_BYTE_COUNT_TRANS(2);
9973                 si->info_level = tvb_get_letohs(tvb, offset);
9974                 if (!pinfo->fd->flags.visited)
9975                         t2i->info_level = si->info_level;
9976                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9977                 COUNT_BYTES_TRANS(2);
9978
9979 #if 0
9980                 /*
9981                  * XXX - "Microsoft Networks SMB File Sharing Protocol
9982                  * Extensions Version 3.0, Document Version 1.11,
9983                  * July 19, 1990" says this is I/O flags, but it's
9984                  * reserved in the SNIA spec, and some clients appear
9985                  * to leave junk in it.
9986                  *
9987                  * Is this some field used only if a particular
9988                  * dialect was negotiated, so that clients can feel
9989                  * safe not setting it if they haven't negotiated that
9990                  * dialect?  Or do the (non-OS/2) clients simply not care
9991                  * about that particular OS/2-oriented dialect?
9992                  */
9993
9994                 /* IO Flag */
9995                 CHECK_BYTE_COUNT_TRANS(2);
9996                 offset = dissect_sfi_ioflag(tvb, tree, offset);
9997                 bc -= 2;
9998 #else
9999                 /* 2 reserved bytes */
10000                 CHECK_BYTE_COUNT_TRANS(2);
10001                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10002                 COUNT_BYTES_TRANS(2);
10003 #endif
10004
10005                 break;
10006         }
10007         case 0x09:      /*TRANS2_FSCTL*/
10008                 /* this call has no parameter block in the request */
10009
10010                 /*
10011                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10012                  * Extensions Version 3.0, Document Version 1.11,
10013                  * July 19, 1990" says this this contains a
10014                  * "File system specific parameter block".  (That means
10015                  * we may not be able to dissect it in any case.)
10016                  */
10017                 break;
10018         case 0x0a:      /*TRANS2_IOCTL2*/
10019                 /* this call has no parameter block in the request */
10020
10021                 /*
10022                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10023                  * Extensions Version 3.0, Document Version 1.11,
10024                  * July 19, 1990" says this this contains a
10025                  * "Device/function specific parameter block".  (That
10026                  * means we may not be able to dissect it in any case.)
10027                  */
10028                 break;
10029         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
10030                 /* Search Attributes */
10031                 CHECK_BYTE_COUNT_TRANS(2);
10032                 offset = dissect_search_attributes(tvb, tree, offset);
10033                 bc -= 2;
10034
10035                 /* Number of changes to wait for */
10036                 CHECK_BYTE_COUNT_TRANS(2);
10037                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10038                 COUNT_BYTES_TRANS(2);
10039
10040                 /* Find Notify information level */
10041                 CHECK_BYTE_COUNT_TRANS(2);
10042                 si->info_level = tvb_get_letohs(tvb, offset);
10043                 if (!pinfo->fd->flags.visited)
10044                         t2i->info_level = si->info_level;
10045                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
10046                 COUNT_BYTES_TRANS(2);
10047
10048                 /* 4 reserved bytes */
10049                 CHECK_BYTE_COUNT_TRANS(4);
10050                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10051                 COUNT_BYTES_TRANS(4);
10052
10053                 /* file name */
10054                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10055                 CHECK_STRING_TRANS(fn);
10056                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10057                         fn);
10058                 COUNT_BYTES_TRANS(fn_len);
10059
10060                 if (check_col(pinfo->cinfo, COL_INFO)) {
10061                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10062                         fn);
10063                 }
10064
10065                 break;
10066         }
10067         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
10068                 /* Monitor handle */
10069                 CHECK_BYTE_COUNT_TRANS(2);
10070                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
10071                 COUNT_BYTES_TRANS(2);
10072
10073                 /* Number of changes to wait for */
10074                 CHECK_BYTE_COUNT_TRANS(2);
10075                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10076                 COUNT_BYTES_TRANS(2);
10077
10078                 break;
10079         }
10080         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10081                 /* 4 reserved bytes */
10082                 CHECK_BYTE_COUNT_TRANS(4);
10083                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10084                 COUNT_BYTES_TRANS(4);
10085
10086                 /* dir name */
10087                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
10088                         FALSE, FALSE, &bc);
10089                 CHECK_STRING_TRANS(fn);
10090                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
10091                         fn);
10092                 COUNT_BYTES_TRANS(fn_len);
10093
10094                 if (check_col(pinfo->cinfo, COL_INFO)) {
10095                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
10096                         fn);
10097                 }
10098                 break;
10099         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10100                 /* XXX unknown structure*/
10101                 break;
10102         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10103                 /* referral level */
10104                 CHECK_BYTE_COUNT_TRANS(2);
10105                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
10106                 COUNT_BYTES_TRANS(2);
10107
10108                 /* file name */
10109                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10110                 CHECK_STRING_TRANS(fn);
10111                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10112                         fn);
10113                 COUNT_BYTES_TRANS(fn_len);
10114
10115                 if (check_col(pinfo->cinfo, COL_INFO)) {
10116                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10117                         fn);
10118                 }
10119
10120                 break;
10121         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10122                 /* file name */
10123                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10124                 CHECK_STRING_TRANS(fn);
10125                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10126                         fn);
10127                 COUNT_BYTES_TRANS(fn_len);
10128
10129                 if (check_col(pinfo->cinfo, COL_INFO)) {
10130                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10131                         fn);
10132                 }
10133
10134                 break;
10135         }
10136
10137         /* ooops there were data we didnt know how to process */
10138         if((offset-old_offset) < bc){
10139                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
10140                     bc - (offset-old_offset), TRUE);
10141                 offset += bc - (offset-old_offset);
10142         }
10143
10144         return offset;
10145 }
10146
10147 /*
10148  * XXX - just use "dissect_connect_flags()" here?
10149  */
10150 static guint16
10151 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10152 {
10153         guint16 mask;
10154         proto_item *item = NULL;
10155         proto_tree *tree = NULL;
10156
10157         mask = tvb_get_letohs(tvb, offset);
10158
10159         if(parent_tree){
10160                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10161                         "Flags: 0x%04x", mask);
10162                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
10163         }
10164
10165         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
10166                 tvb, offset, 2, mask);
10167         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
10168                 tvb, offset, 2, mask);
10169
10170         return mask;
10171 }
10172
10173
10174 static int
10175 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10176 {
10177         guint16 mask;
10178         proto_item *item = NULL;
10179         proto_tree *tree = NULL;
10180
10181         mask = tvb_get_letohs(tvb, offset);
10182
10183         if(parent_tree){
10184                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10185                         "Flags: 0x%04x", mask);
10186                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
10187         }
10188
10189         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
10190                 tvb, offset, 2, mask);
10191         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
10192                 tvb, offset, 2, mask);
10193
10194         offset += 2;
10195         return offset;
10196 }
10197
10198 static int
10199 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10200 {
10201         guint16 mask;
10202         proto_item *item = NULL;
10203         proto_tree *tree = NULL;
10204
10205         mask = tvb_get_letohs(tvb, offset);
10206
10207         if(parent_tree){
10208                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10209                         "Flags: 0x%04x", mask);
10210                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
10211         }
10212
10213         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
10214                 tvb, offset, 2, mask);
10215
10216         offset += 2;
10217
10218         return offset;
10219 }
10220
10221
10222 /* dfs inconsistency data  (4.4.2)
10223 */
10224 static int
10225 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
10226     proto_tree *tree, int offset, guint16 *bcp)
10227 {
10228         smb_info_t *si = pinfo->private_data;
10229         int fn_len;
10230         const char *fn;
10231
10232         /*XXX shouldn this data hold version and size? unclear from doc*/
10233         /* referral version */
10234         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10235         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
10236         COUNT_BYTES_TRANS_SUBR(2);
10237
10238         /* referral size */
10239         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10240         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
10241         COUNT_BYTES_TRANS_SUBR(2);
10242
10243         /* referral server type */
10244         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10245         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10246         COUNT_BYTES_TRANS_SUBR(2);
10247
10248         /* referral flags */
10249         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10250         offset = dissect_dfs_referral_flags(tvb, tree, offset);
10251         *bcp -= 2;
10252
10253         /* node name */
10254         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10255         CHECK_STRING_TRANS_SUBR(fn);
10256         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10257                 fn);
10258         COUNT_BYTES_TRANS_SUBR(fn_len);
10259
10260         return offset;
10261 }
10262
10263 /* get dfs referral data  (4.4.1)
10264 */
10265 static int
10266 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
10267     proto_tree *tree, int offset, guint16 *bcp)
10268 {
10269         smb_info_t *si = pinfo->private_data;
10270         guint16 numref;
10271         guint16 refsize;
10272         guint16 pathoffset;
10273         guint16 altpathoffset;
10274         guint16 nodeoffset;
10275         int fn_len;
10276         int stroffset;
10277         int offsetoffset;
10278         guint16 save_bc;
10279         const char *fn;
10280         int unklen;
10281         int ucstring_end;
10282         int ucstring_len;
10283
10284         /* path consumed */
10285         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10286         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
10287         COUNT_BYTES_TRANS_SUBR(2);
10288
10289         /* num referrals */
10290         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10291         numref = tvb_get_letohs(tvb, offset);
10292         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
10293         COUNT_BYTES_TRANS_SUBR(2);
10294
10295         /* get dfs flags */
10296         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10297         offset = dissect_get_dfs_flags(tvb, tree, offset);
10298         *bcp -= 2;
10299
10300         /* XXX - in at least one capture there appears to be 2 bytes
10301            of stuff after the Dfs flags, perhaps so that the header
10302            in front of the referral list is a multiple of 4 bytes long. */
10303         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10304         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
10305         COUNT_BYTES_TRANS_SUBR(2);
10306
10307         /* if there are any referrals */
10308         if(numref){
10309                 proto_item *ref_item = NULL;
10310                 proto_tree *ref_tree = NULL;
10311                 int old_offset=offset;
10312
10313                 if(tree){
10314                         ref_item = proto_tree_add_text(tree,
10315                                 tvb, offset, *bcp, "Referrals");
10316                         ref_tree = proto_item_add_subtree(ref_item,
10317                                 ett_smb_dfs_referrals);
10318                 }
10319                 ucstring_end = -1;
10320
10321                 while(numref--){
10322                         proto_item *ri = NULL;
10323                         proto_tree *rt = NULL;
10324                         int old_offset=offset;
10325                         guint16 version;
10326
10327                         if(tree){
10328                                 ri = proto_tree_add_text(ref_tree,
10329                                         tvb, offset, *bcp, "Referral");
10330                                 rt = proto_item_add_subtree(ri,
10331                                         ett_smb_dfs_referral);
10332                         }
10333
10334                         /* referral version */
10335                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10336                         version = tvb_get_letohs(tvb, offset);
10337                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
10338                                 tvb, offset, 2, version);
10339                         COUNT_BYTES_TRANS_SUBR(2);
10340
10341                         /* referral size */
10342                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10343                         refsize = tvb_get_letohs(tvb, offset);
10344                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
10345                         COUNT_BYTES_TRANS_SUBR(2);
10346
10347                         /* referral server type */
10348                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10349                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10350                         COUNT_BYTES_TRANS_SUBR(2);
10351
10352                         /* referral flags */
10353                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10354                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
10355                         *bcp -= 2;
10356
10357                         switch(version){
10358
10359                         case 1:
10360                                 /* node name */
10361                                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10362                                 CHECK_STRING_TRANS_SUBR(fn);
10363                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10364                                         fn);
10365                                 COUNT_BYTES_TRANS_SUBR(fn_len);
10366                                 break;
10367
10368                         case 2:
10369                         case 3: /* XXX - like version 2, but not identical;
10370                                    seen in a capture, but the format isn't
10371                                    documented */
10372                                 /* proximity */
10373                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10374                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
10375                                 COUNT_BYTES_TRANS_SUBR(2);
10376
10377                                 /* ttl */
10378                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10379                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
10380                                 COUNT_BYTES_TRANS_SUBR(2);
10381
10382                                 /* path offset */
10383                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10384                                 pathoffset = tvb_get_letohs(tvb, offset);
10385                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
10386                                 COUNT_BYTES_TRANS_SUBR(2);
10387
10388                                 /* alt path offset */
10389                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10390                                 altpathoffset = tvb_get_letohs(tvb, offset);
10391                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
10392                                 COUNT_BYTES_TRANS_SUBR(2);
10393
10394                                 /* node offset */
10395                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10396                                 nodeoffset = tvb_get_letohs(tvb, offset);
10397                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
10398                                 COUNT_BYTES_TRANS_SUBR(2);
10399
10400                                 /* path */
10401                                 if (pathoffset != 0) {
10402                                         stroffset = old_offset + pathoffset;
10403                                         offsetoffset = stroffset - offset;
10404                                         if (offsetoffset > 0 &&
10405                                             *bcp > offsetoffset) {
10406                                                 save_bc = *bcp;
10407                                                 *bcp -= offsetoffset;
10408                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10409                                                 CHECK_STRING_TRANS_SUBR(fn);
10410                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
10411                                                         fn);
10412                                                 stroffset += fn_len;
10413                                                 if (ucstring_end < stroffset)
10414                                                         ucstring_end = stroffset;
10415                                                 *bcp = save_bc;
10416                                         }
10417                                 }
10418
10419                                 /* alt path */
10420                                 if (altpathoffset != 0) {
10421                                         stroffset = old_offset + altpathoffset;
10422                                         offsetoffset = stroffset - offset;
10423                                         if (offsetoffset > 0 &&
10424                                             *bcp > offsetoffset) {
10425                                                 save_bc = *bcp;
10426                                                 *bcp -= offsetoffset;
10427                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10428                                                 CHECK_STRING_TRANS_SUBR(fn);
10429                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
10430                                                         fn);
10431                                                 stroffset += fn_len;
10432                                                 if (ucstring_end < stroffset)
10433                                                         ucstring_end = stroffset;
10434                                                 *bcp = save_bc;
10435                                         }
10436                                 }
10437
10438                                 /* node */
10439                                 if (nodeoffset != 0) {
10440                                         stroffset = old_offset + nodeoffset;
10441                                         offsetoffset = stroffset - offset;
10442                                         if (offsetoffset > 0 &&
10443                                             *bcp > offsetoffset) {
10444                                                 save_bc = *bcp;
10445                                                 *bcp -= offsetoffset;
10446                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10447                                                 CHECK_STRING_TRANS_SUBR(fn);
10448                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
10449                                                         fn);
10450                                                 stroffset += fn_len;
10451                                                 if (ucstring_end < stroffset)
10452                                                         ucstring_end = stroffset;
10453                                                 *bcp = save_bc;
10454                                         }
10455                                 }
10456                                 break;
10457                         }
10458
10459                         /*
10460                          * Show anything beyond the length of the referral
10461                          * as unknown data.
10462                          */
10463                         unklen = (old_offset + refsize) - offset;
10464                         if (unklen < 0) {
10465                                 /*
10466                                  * XXX - the length is bogus.
10467                                  */
10468                                 unklen = 0;
10469                         }
10470                         if (unklen != 0) {
10471                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
10472                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
10473                                     offset, unklen, TRUE);
10474                                 COUNT_BYTES_TRANS_SUBR(unklen);
10475                         }
10476
10477                         proto_item_set_len(ri, offset-old_offset);
10478                 }
10479
10480                 /*
10481                  * Treat the offset past the end of the last Unicode
10482                  * string after the referrals (if any) as the last
10483                  * offset.
10484                  */
10485                 if (ucstring_end > offset) {
10486                         ucstring_len = ucstring_end - offset;
10487                         if (*bcp < ucstring_len)
10488                                 ucstring_len = *bcp;
10489                         offset += ucstring_len;
10490                         *bcp -= ucstring_len;
10491                 }
10492                 proto_item_set_len(ref_item, offset-old_offset);
10493         }
10494
10495         return offset;
10496 }
10497
10498
10499 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
10500    as described in 4.2.14.1
10501 */
10502 static int
10503 dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10504     int offset, guint16 *bcp, gboolean *trunc)
10505 {
10506         /* create time */
10507         CHECK_BYTE_COUNT_SUBR(4);
10508         offset = dissect_smb_datetime(tvb, tree, offset,
10509                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
10510                 FALSE);
10511         *bcp -= 4;
10512
10513         /* access time */
10514         CHECK_BYTE_COUNT_SUBR(4);
10515         offset = dissect_smb_datetime(tvb, tree, offset,
10516                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
10517                 FALSE);
10518         *bcp -= 4;
10519
10520         /* last write time */
10521         CHECK_BYTE_COUNT_SUBR(4);
10522         offset = dissect_smb_datetime(tvb, tree, offset,
10523                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
10524                 FALSE);
10525         *bcp -= 4;
10526
10527         /* data size */
10528         CHECK_BYTE_COUNT_SUBR(4);
10529         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10530         COUNT_BYTES_SUBR(4);
10531
10532         /* allocation size */
10533         CHECK_BYTE_COUNT_SUBR(4);
10534         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10535         COUNT_BYTES_SUBR(4);
10536
10537         /* File Attributes */
10538         CHECK_BYTE_COUNT_SUBR(2);
10539         offset = dissect_file_attributes(tvb, tree, offset, 2);
10540         *bcp -= 2;
10541
10542         /* ea size */
10543         CHECK_BYTE_COUNT_SUBR(4);
10544         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10545         COUNT_BYTES_SUBR(4);
10546
10547         *trunc = FALSE;
10548         return offset;
10549 }
10550
10551 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
10552    as described in 4.2.14.2
10553 */
10554 static int
10555 dissect_4_2_14_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10556     int offset, guint16 *bcp, gboolean *trunc)
10557 {
10558         /* list length */
10559         CHECK_BYTE_COUNT_SUBR(4);
10560         proto_tree_add_item(tree, hf_smb_list_length, tvb, offset, 4, TRUE);
10561         COUNT_BYTES_SUBR(4);
10562
10563         *trunc = FALSE;
10564         return offset;
10565 }
10566
10567 /* this dissects the SMB_INFO_IS_NAME_VALID
10568    as described in 4.2.14.3
10569 */
10570 static int
10571 dissect_4_2_14_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10572     int offset, guint16 *bcp, gboolean *trunc)
10573 {
10574         smb_info_t *si = pinfo->private_data;
10575         int fn_len;
10576         const char *fn;
10577
10578         /* file name */
10579         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10580         CHECK_STRING_SUBR(fn);
10581         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10582                 fn);
10583         COUNT_BYTES_SUBR(fn_len);
10584
10585         *trunc = FALSE;
10586         return offset;
10587 }
10588
10589 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
10590    as described in 4.2.14.4
10591 */
10592 static int
10593 dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10594     int offset, guint16 *bcp, gboolean *trunc)
10595 {
10596         /* create time */
10597         CHECK_BYTE_COUNT_SUBR(8);
10598         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
10599         *bcp -= 8;
10600
10601         /* access time */
10602         CHECK_BYTE_COUNT_SUBR(8);
10603         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
10604         *bcp -= 8;
10605
10606         /* last write time */
10607         CHECK_BYTE_COUNT_SUBR(8);
10608         offset = dissect_smb_64bit_time(tvb, tree, offset,
10609                 hf_smb_last_write_time);
10610         *bcp -= 8;
10611
10612         /* last change time */
10613         CHECK_BYTE_COUNT_SUBR(8);
10614         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
10615         *bcp -= 8;
10616
10617         /* File Attributes */
10618         CHECK_BYTE_COUNT_SUBR(4);
10619         offset = dissect_file_attributes(tvb, tree, offset, 4);
10620         *bcp -= 4;
10621
10622         *trunc = FALSE;
10623         return offset;
10624 }
10625
10626 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
10627    as described in 4.2.14.5
10628 */
10629 static int
10630 dissect_4_2_14_5(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10631     int offset, guint16 *bcp, gboolean *trunc)
10632 {
10633         /* allocation size */
10634         CHECK_BYTE_COUNT_SUBR(8);
10635         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10636         COUNT_BYTES_SUBR(8);
10637
10638         /* end of file */
10639         CHECK_BYTE_COUNT_SUBR(8);
10640         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10641         COUNT_BYTES_SUBR(8);
10642
10643         /* number of links */
10644         CHECK_BYTE_COUNT_SUBR(4);
10645         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
10646         COUNT_BYTES_SUBR(4);
10647
10648         /* delete pending */
10649         CHECK_BYTE_COUNT_SUBR(1);
10650         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
10651         COUNT_BYTES_SUBR(1);
10652
10653         /* is directory */
10654         CHECK_BYTE_COUNT_SUBR(1);
10655         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
10656         COUNT_BYTES_SUBR(1);
10657
10658         *trunc = FALSE;
10659         return offset;
10660 }
10661
10662 /* this dissects the SMB_QUERY_FILE_EA_INFO
10663    as described in 4.2.14.6
10664 */
10665 static int
10666 dissect_4_2_14_6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10667     int offset, guint16 *bcp, gboolean *trunc)
10668 {
10669         /* ea size */
10670         CHECK_BYTE_COUNT_SUBR(4);
10671         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10672         COUNT_BYTES_SUBR(4);
10673
10674         *trunc = FALSE;
10675         return offset;
10676 }
10677
10678 /* this dissects the SMB_QUERY_FILE_NAME_INFO
10679    as described in 4.2.14.7
10680    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
10681    as described in 4.2.14.9
10682 */
10683 static int
10684 dissect_4_2_14_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10685     int offset, guint16 *bcp, gboolean *trunc)
10686 {
10687         smb_info_t *si = pinfo->private_data;
10688         int fn_len;
10689         const char *fn;
10690
10691         /* file name len */
10692         CHECK_BYTE_COUNT_SUBR(4);
10693         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
10694         COUNT_BYTES_SUBR(4);
10695
10696         /* file name */
10697         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10698         CHECK_STRING_SUBR(fn);
10699         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10700                 fn);
10701         COUNT_BYTES_SUBR(fn_len);
10702
10703         *trunc = FALSE;
10704         return offset;
10705 }
10706
10707 /* this dissects the SMB_QUERY_FILE_ALL_INFO
10708    as described in 4.2.14.8
10709 */
10710 static int
10711 dissect_4_2_14_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10712     int offset, guint16 *bcp, gboolean *trunc)
10713 {
10714
10715         offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp, trunc);
10716         if (*trunc) {
10717                 return offset;
10718         }
10719         offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp, trunc);
10720         if (*trunc) {
10721                 return offset;
10722         }
10723
10724         /* index number */
10725         CHECK_BYTE_COUNT_SUBR(8);
10726         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
10727         COUNT_BYTES_SUBR(8);
10728
10729         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
10730         if (*trunc)
10731                 return offset;
10732
10733         /* access flags */
10734         CHECK_BYTE_COUNT_SUBR(4);
10735         offset = dissect_smb_access_mask(tvb, tree, offset);
10736         COUNT_BYTES_SUBR(4);
10737
10738         /* index number */
10739         CHECK_BYTE_COUNT_SUBR(8);
10740         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
10741         COUNT_BYTES_SUBR(8);
10742
10743         /* current offset */
10744         CHECK_BYTE_COUNT_SUBR(8);
10745         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
10746         COUNT_BYTES_SUBR(8);
10747
10748         /* mode */
10749         CHECK_BYTE_COUNT_SUBR(4);
10750         offset = dissect_nt_create_options(tvb, tree, offset);
10751         *bcp -= 4;
10752
10753         /* alignment */
10754         CHECK_BYTE_COUNT_SUBR(4);
10755         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
10756         COUNT_BYTES_SUBR(4);
10757
10758         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
10759
10760         return offset;
10761 }
10762
10763 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
10764    as described in 4.2.14.10
10765 */
10766 static int
10767 dissect_4_2_14_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10768     int offset, guint16 *bcp, gboolean *trunc)
10769 {
10770         proto_item *item;
10771         proto_tree *tree;
10772         int old_offset;
10773         guint32 neo;
10774         smb_info_t *si = pinfo->private_data;
10775         int fn_len;
10776         const char *fn;
10777         int padcnt;
10778
10779         for (;;) {
10780                 old_offset = offset;
10781
10782                 /* next entry offset */
10783                 CHECK_BYTE_COUNT_SUBR(4);
10784                 if(parent_tree){
10785                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
10786                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10787                 } else {
10788                         item = NULL;
10789                         tree = NULL;
10790                 }
10791
10792                 neo = tvb_get_letohl(tvb, offset);
10793                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10794                 COUNT_BYTES_SUBR(4);
10795
10796                 /* stream name len */
10797                 CHECK_BYTE_COUNT_SUBR(4);
10798                 fn_len = tvb_get_letohl(tvb, offset);
10799                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
10800                 COUNT_BYTES_SUBR(4);
10801
10802                 /* stream size */
10803                 CHECK_BYTE_COUNT_SUBR(8);
10804                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
10805                 COUNT_BYTES_SUBR(8);
10806
10807                 /* allocation size */
10808                 CHECK_BYTE_COUNT_SUBR(8);
10809                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10810                 COUNT_BYTES_SUBR(8);
10811
10812                 /* stream name */
10813                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
10814                 CHECK_STRING_SUBR(fn);
10815                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
10816                         fn);
10817                 COUNT_BYTES_SUBR(fn_len);
10818
10819                 proto_item_append_text(item, ": %s", fn);
10820                 proto_item_set_len(item, offset-old_offset);
10821
10822                 if (neo == 0)
10823                         break;  /* no more structures */
10824
10825                 /* skip to next structure */
10826                 padcnt = (old_offset + neo) - offset;
10827                 if (padcnt < 0) {
10828                         /*
10829                          * XXX - this is bogus; flag it?
10830                          */
10831                         padcnt = 0;
10832                 }
10833                 if (padcnt != 0) {
10834                         CHECK_BYTE_COUNT_SUBR(padcnt);
10835                         COUNT_BYTES_SUBR(padcnt);
10836                 }
10837         }
10838
10839         *trunc = FALSE;
10840         return offset;
10841 }
10842
10843 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
10844    as described in 4.2.14.11
10845 */
10846 static int
10847 dissect_4_2_14_11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10848     int offset, guint16 *bcp, gboolean *trunc)
10849 {
10850         /* compressed file size */
10851         CHECK_BYTE_COUNT_SUBR(8);
10852         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
10853         COUNT_BYTES_SUBR(8);
10854
10855         /* compression format */
10856         CHECK_BYTE_COUNT_SUBR(2);
10857         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
10858         COUNT_BYTES_SUBR(2);
10859
10860         /* compression unit shift */
10861         CHECK_BYTE_COUNT_SUBR(1);
10862         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
10863         COUNT_BYTES_SUBR(1);
10864
10865         /* compression chunk shift */
10866         CHECK_BYTE_COUNT_SUBR(1);
10867         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
10868         COUNT_BYTES_SUBR(1);
10869
10870         /* compression cluster shift */
10871         CHECK_BYTE_COUNT_SUBR(1);
10872         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
10873         COUNT_BYTES_SUBR(1);
10874
10875         /* 3 reserved bytes */
10876         CHECK_BYTE_COUNT_SUBR(3);
10877         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
10878         COUNT_BYTES_SUBR(3);
10879
10880         *trunc = FALSE;
10881         return offset;
10882 }
10883
10884
10885
10886 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION*/
10887 static int
10888 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
10889     int offset, guint16 *bcp)
10890 {
10891         smb_info_t *si;
10892         gboolean trunc;
10893
10894         if(!*bcp){
10895                 return offset;
10896         }
10897
10898         si = (smb_info_t *)pinfo->private_data;
10899         switch(si->info_level){
10900         case 1:         /*Info Standard*/
10901         case 2:         /*Info Query EA Size*/
10902                 offset = dissect_4_2_14_1(tvb, pinfo, tree, offset, bcp,
10903                     &trunc);
10904                 break;
10905         case 3:         /*Info Query EAs From List*/
10906         case 4:         /*Info Query All EAs*/
10907                 offset = dissect_4_2_14_2(tvb, pinfo, tree, offset, bcp,
10908                     &trunc);
10909                 break;
10910         case 6:         /*Info Is Name Valid*/
10911                 offset = dissect_4_2_14_3(tvb, pinfo, tree, offset, bcp,
10912                     &trunc);
10913                 break;
10914         case 0x0101:    /*Query File Basic Info*/
10915         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
10916                 offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp,
10917                     &trunc);
10918                 break;
10919         case 0x0102:    /*Query File Standard Info*/
10920         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
10921                 offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp,
10922                     &trunc);
10923                 break;
10924         case 0x0103:    /*Query File EA Info*/
10925         case 1007:      /* SMB_FILE_EA_INFORMATION */
10926                 offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp,
10927                     &trunc);
10928                 break;
10929         case 0x0104:    /*Query File Name Info*/
10930         case 1009:      /* SMB_FILE_NAME_INFORMATION */
10931                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
10932                     &trunc);
10933                 break;
10934         case 0x0107:    /*Query File All Info*/
10935         case 1018:      /* SMB_FILE_ALL_INFORMATION */
10936                 offset = dissect_4_2_14_8(tvb, pinfo, tree, offset, bcp,
10937                     &trunc);
10938                 break;
10939         case 0x0108:    /*Query File Alt File Info*/
10940         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
10941                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
10942                     &trunc);
10943                 break;
10944         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
10945                 ((smb_info_t *)(pinfo->private_data))->unicode = TRUE;
10946         case 0x0109:    /*Query File Stream Info*/
10947                 offset = dissect_4_2_14_10(tvb, pinfo, tree, offset, bcp,
10948                     &trunc);
10949                 break;
10950         case 0x010b:    /*Query File Compression Info*/
10951         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
10952                 offset = dissect_4_2_14_11(tvb, pinfo, tree, offset, bcp,
10953                     &trunc);
10954                 break;
10955         case 0x0200:    /*Set File Unix Basic*/
10956                 /* XXX add this from the SNIA doc */
10957                 break;
10958         case 0x0201:    /*Set File Unix Link*/
10959                 /* XXX add this from the SNIA doc */
10960                 break;
10961         case 0x0202:    /*Set File Unix HardLink*/
10962                 /* XXX add this from the SNIA doc */
10963                 break;
10964         }
10965
10966         return offset;
10967 }
10968
10969
10970 static const true_false_string tfs_quota_flags_deny_disk = {
10971         "DENY DISK SPACE for users exceeding quota limit",
10972         "Do NOT deny disk space for users exceeding quota limit"
10973 };
10974 static const true_false_string tfs_quota_flags_log_limit = {
10975         "LOG EVENT when a user exceeds their QUOTA LIMIT",
10976         "Do NOT log event when a user exceeds their quota limit"
10977 };
10978 static const true_false_string tfs_quota_flags_log_warning = {
10979         "LOG EVENT when a user exceeds their WARNING LEVEL",
10980         "Do NOT log event when a user exceeds their warning level"
10981 };
10982 static const true_false_string tfs_quota_flags_enabled = {
10983         "Quotas are ENABLED of this fs",
10984         "Quotas are NOT enabled on this fs"
10985 };
10986 static void
10987 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10988 {
10989         guint8 mask;
10990         proto_item *item = NULL;
10991         proto_tree *tree = NULL;
10992
10993         mask = tvb_get_guint8(tvb, offset);
10994
10995         if(parent_tree){
10996                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
10997                         "Quota Flags: 0x%02x %s", mask,
10998                         mask?"Enabled":"Disabled");
10999                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
11000         }
11001
11002         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
11003                 tvb, offset, 1, mask);
11004         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
11005                 tvb, offset, 1, mask);
11006         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
11007                 tvb, offset, 1, mask);
11008
11009         if(mask && (!(mask&0x01))){
11010                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
11011                         tvb, offset, 1, 0x01);
11012         } else {
11013                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
11014                         tvb, offset, 1, mask);
11015         }
11016
11017 }
11018
11019 static int
11020 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
11021 {
11022         /* first 24 bytes are unknown */
11023         CHECK_BYTE_COUNT_TRANS_SUBR(24);
11024         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11025                     offset, 24, TRUE);
11026         COUNT_BYTES_TRANS_SUBR(24);
11027
11028         /* number of bytes for quota warning */
11029         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11030         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
11031         COUNT_BYTES_TRANS_SUBR(8);
11032
11033         /* number of bytes for quota limit */
11034         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11035         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
11036         COUNT_BYTES_TRANS_SUBR(8);
11037
11038         /* one byte of quota flags */
11039         CHECK_BYTE_COUNT_TRANS_SUBR(1);
11040         dissect_quota_flags(tvb, tree, offset);
11041         COUNT_BYTES_TRANS_SUBR(1);
11042
11043         /* these 7 bytes are unknown */
11044         CHECK_BYTE_COUNT_TRANS_SUBR(7);
11045         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11046                     offset, 7, TRUE);
11047         COUNT_BYTES_TRANS_SUBR(7);
11048
11049         return offset;
11050 }
11051
11052 static int
11053 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
11054     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
11055 {
11056         proto_item *item = NULL;
11057         proto_tree *tree = NULL;
11058         smb_info_t *si;
11059
11060         si = (smb_info_t *)pinfo->private_data;
11061
11062         if(parent_tree){
11063                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
11064                                 "%s Data",
11065                                 val_to_str(subcmd, trans2_cmd_vals,
11066                                                 "Unknown (0x%02x)"));
11067                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
11068         }
11069
11070         switch(subcmd){
11071         case 0x00:      /*TRANS2_OPEN2*/
11072                 /* XXX dont know how to decode FEAList */
11073                 break;
11074         case 0x01:      /*TRANS2_FIND_FIRST2*/
11075                 /* XXX dont know how to decode FEAList */
11076                 break;
11077         case 0x02:      /*TRANS2_FIND_NEXT2*/
11078                 /* XXX dont know how to decode FEAList */
11079                 break;
11080         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
11081                 /* no data field in this request */
11082                 break;
11083         case 0x04:      /* TRANS2_SET_QUOTA */
11084                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
11085                 break;
11086         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
11087                 /* no data field in this request */
11088                 /*
11089                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11090                  * Extensions Version 3.0, Document Version 1.11,
11091                  * July 19, 1990" says there may be "Additional
11092                  * FileInfoLevel dependent information" here.
11093                  *
11094                  * Was that just a cut-and-pasteo?
11095                  * TRANS2_SET_PATH_INFORMATION *does* have that information
11096                  * here.
11097                  */
11098                 break;
11099         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
11100                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
11101                 break;
11102         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
11103                 /* no data field in this request */
11104                 /*
11105                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11106                  * Extensions Version 3.0, Document Version 1.11,
11107                  * July 19, 1990" says there may be "Additional
11108                  * FileInfoLevel dependent information" here.
11109                  *
11110                  * Was that just a cut-and-pasteo?
11111                  * TRANS2_SET_FILE_INFORMATION *does* have that information
11112                  * here.
11113                  */
11114                 break;
11115         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
11116                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
11117                 break;
11118         case 0x09:      /*TRANS2_FSCTL*/
11119                 /*XXX dont know how to decode this yet */
11120
11121                 /*
11122                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11123                  * Extensions Version 3.0, Document Version 1.11,
11124                  * July 19, 1990" says this this contains a
11125                  * "File system specific data block".  (That means we
11126                  * may not be able to dissect it in any case.)
11127                  */
11128                 break;
11129         case 0x0a:      /*TRANS2_IOCTL2*/
11130                 /*XXX dont know how to decode this yet */
11131
11132                 /*
11133                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11134                  * Extensions Version 3.0, Document Version 1.11,
11135                  * July 19, 1990" says this this contains a
11136                  * "Device/function specific data block".  (That
11137                  * means we may not be able to dissect it in any case.)
11138                  */
11139                 break;
11140         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11141                 /*XXX dont know how to decode this yet */
11142
11143                 /*
11144                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11145                  * Extensions Version 3.0, Document Version 1.11,
11146                  * July 19, 1990" says this this contains "additional
11147                  * level dependent match data".
11148                  */
11149                 break;
11150         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11151                 /*XXX dont know how to decode this yet */
11152
11153                 /*
11154                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11155                  * Extensions Version 3.0, Document Version 1.11,
11156                  * July 19, 1990" says this this contains "additional
11157                  * level dependent monitor information".
11158                  */
11159                 break;
11160         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11161                 /* XXX optional FEAList, unknown what FEAList looks like*/
11162                 break;
11163         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11164                 /*XXX dont know how to decode this yet */
11165                 break;
11166         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11167                 /* no data field in this request */
11168                 break;
11169         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11170                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
11171                 break;
11172         }
11173
11174         /* ooops there were data we didnt know how to process */
11175         if(dc != 0){
11176                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
11177                 offset += dc;
11178         }
11179
11180         return offset;
11181 }
11182
11183
11184 static void
11185 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
11186     proto_tree *tree)
11187 {
11188         int i;
11189         int offset;
11190         guint length;
11191
11192         /*
11193          * Show the setup words.
11194          */
11195         if (s_tvb != NULL) {
11196                 length = tvb_reported_length(s_tvb);
11197                 for (i = 0, offset = 0; length >= 2;
11198                     i++, offset += 2, length -= 2) {
11199                         /*
11200                          * XXX - add a setup word filterable field?
11201                          */
11202                         proto_tree_add_text(tree, s_tvb, offset, 2,
11203                             "Setup Word %d: 0x%04x", i,
11204                             tvb_get_letohs(s_tvb, offset));
11205                 }
11206         }
11207
11208         /*
11209          * Show the parameters, if any.
11210          */
11211         if (p_tvb != NULL) {
11212                 length = tvb_reported_length(p_tvb);
11213                 if (length != 0) {
11214                         proto_tree_add_text(tree, p_tvb, 0, length,
11215                             "Parameters: %s",
11216                             tvb_bytes_to_str(p_tvb, 0, length));
11217                 }
11218         }
11219
11220         /*
11221          * Show the data, if any.
11222          */
11223         if (d_tvb != NULL) {
11224                 length = tvb_reported_length(d_tvb);
11225                 if (length != 0) {
11226                         proto_tree_add_text(tree, d_tvb, 0, length,
11227                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
11228                 }
11229         }
11230 }
11231
11232 /* This routine handles the following 4 calls
11233    Transaction  0x25
11234    Transaction Secondary 0x26
11235    Transaction2 0x32
11236    Transaction2 Secondary 0x33
11237 */
11238 static int
11239 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
11240 {
11241         guint8 wc, sc=0;
11242         int so=offset;
11243         int sl=0;
11244         int spo=offset;
11245         int spc=0;
11246         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
11247         int subcmd = -1;
11248         guint32 to;
11249         int an_len;
11250         const char *an = NULL;
11251         smb_info_t *si;
11252         smb_transact2_info_t *t2i;
11253         smb_transact_info_t *tri;
11254         guint16 bc;
11255         int padcnt;
11256         gboolean dissected_trans;
11257
11258         si = (smb_info_t *)pinfo->private_data;
11259
11260         WORD_COUNT;
11261
11262         if(wc==8){
11263                 /*secondary client request*/
11264
11265                 /* total param count, only a 16bit integer here*/
11266                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11267                 offset += 2;
11268
11269                 /* total data count , only 16bit integer here*/
11270                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11271                 offset += 2;
11272
11273                 /* param count */
11274                 pc = tvb_get_letohs(tvb, offset);
11275                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11276                 offset += 2;
11277
11278                 /* param offset */
11279                 po = tvb_get_letohs(tvb, offset);
11280                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11281                 offset += 2;
11282
11283                 /* param disp */
11284                 pd = tvb_get_letohs(tvb, offset);
11285                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
11286                 offset += 2;
11287
11288                 /* data count */
11289                 dc = tvb_get_letohs(tvb, offset);
11290                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11291                 offset += 2;
11292
11293                 /* data offset */
11294                 od = tvb_get_letohs(tvb, offset);
11295                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11296                 offset += 2;
11297
11298                 /* data disp */
11299                 dd = tvb_get_letohs(tvb, offset);
11300                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
11301                 offset += 2;
11302
11303                 if(si->cmd==SMB_COM_TRANSACTION2){
11304                         guint16 fid;
11305
11306                         /* fid */
11307                         fid = tvb_get_letohs(tvb, offset);
11308                         add_fid(tvb, pinfo, tree, offset, 2, fid);
11309
11310                         offset += 2;
11311                 }
11312
11313                 /* There are no setup words. */
11314                 so = offset;
11315                 sc = 0;
11316                 sl = 0;
11317         } else {
11318                 /* it is not a secondary request */
11319
11320                 /* total param count , only a 16 bit integer here*/
11321                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11322                 offset += 2;
11323
11324                 /* total data count , only 16bit integer here*/
11325                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11326                 offset += 2;
11327
11328                 /* max param count , only 16bit integer here*/
11329                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11330                 offset += 2;
11331
11332                 /* max data count, only 16bit integer here*/
11333                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11334                 offset += 2;
11335
11336                 /* max setup count, only 16bit integer here*/
11337                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
11338                 offset += 1;
11339
11340                 /* reserved byte */
11341                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11342                 offset += 1;
11343
11344                 /* transaction flags */
11345                 tf = dissect_transaction_flags(tvb, tree, offset);
11346                 offset += 2;
11347
11348                 /* timeout */
11349                 to = tvb_get_letohl(tvb, offset);
11350                 if (to == 0)
11351                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
11352                 else if (to == 0xffffffff)
11353                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
11354                 else
11355                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
11356                 offset += 4;
11357
11358                 /* 2 reserved bytes */
11359                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
11360                 offset += 2;
11361
11362                 /* param count */
11363                 pc = tvb_get_letohs(tvb, offset);
11364                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11365                 offset += 2;
11366
11367                 /* param offset */
11368                 po = tvb_get_letohs(tvb, offset);
11369                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11370                 offset += 2;
11371
11372                 /* param displacement is zero here */
11373                 pd = 0;
11374
11375                 /* data count */
11376                 dc = tvb_get_letohs(tvb, offset);
11377                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11378                 offset += 2;
11379
11380                 /* data offset */
11381                 od = tvb_get_letohs(tvb, offset);
11382                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11383                 offset += 2;
11384
11385                 /* data displacement is zero here */
11386                 dd = 0;
11387
11388                 /* setup count */
11389                 sc = tvb_get_guint8(tvb, offset);
11390                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
11391                 offset += 1;
11392
11393                 /* reserved byte */
11394                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11395                 offset += 1;
11396
11397                 /* this is where the setup bytes, if any start */
11398                 so = offset;
11399                 sl = sc*2;
11400
11401                 /* if there were any setup bytes, decode them */
11402                 if(sc){
11403                         switch(si->cmd){
11404
11405                         case SMB_COM_TRANSACTION2:
11406                                 /* TRANSACTION2 only has one setup word and
11407                                    that is the subcommand code.
11408
11409                                    XXX - except for TRANS2_FSCTL
11410                                    and TRANS2_IOCTL. */
11411                                 subcmd = tvb_get_letohs(tvb, offset);
11412                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
11413                                     tvb, offset, 2, subcmd);
11414                                 if (check_col(pinfo->cinfo, COL_INFO)) {
11415                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11416                                             val_to_str(subcmd, trans2_cmd_vals,
11417                                                 "Unknown (0x%02x)"));
11418                                 }
11419                                 if (!si->unidir) {
11420                                         if(!pinfo->fd->flags.visited){
11421                                                 /*
11422                                                  * Allocate a new
11423                                                  * smb_transact2_info_t
11424                                                  * structure.
11425                                                  */
11426                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
11427                                                 t2i->subcmd = subcmd;
11428                                                 t2i->info_level = -1;
11429                                                 t2i->resume_keys = FALSE;
11430                                                 si->sip->extra_info = t2i;
11431                                         }
11432                                 }
11433
11434                                 /*
11435                                  * XXX - process TRANS2_FSCTL and
11436                                  * TRANS2_IOCTL setup words here.
11437                                  */
11438                                 break;
11439
11440                         case SMB_COM_TRANSACTION:
11441                                 /* TRANSACTION setup words processed below */
11442                                 break;
11443                         }
11444
11445                         offset += sl;
11446                 }
11447         }
11448
11449         BYTE_COUNT;
11450
11451         if(wc!=8){
11452                 /* primary request */
11453                 /* name is NULL if transaction2 */
11454                 if(si->cmd == SMB_COM_TRANSACTION){
11455                         /* Transaction Name */
11456                         an = get_unicode_or_ascii_string(tvb, &offset,
11457                                 si->unicode, &an_len, FALSE, FALSE, &bc);
11458                         if (an == NULL)
11459                                 goto endofcommand;
11460                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
11461                                 offset, an_len, an);
11462                         COUNT_BYTES(an_len);
11463                 }
11464         }
11465
11466         /*
11467          * The pipe or mailslot arguments for Transaction start with
11468          * the first setup word (or where the first setup word would
11469          * be if there were any setup words), and run to the current
11470          * offset (which could mean that there aren't any).
11471          */
11472         spo = so;
11473         spc = offset - spo;
11474
11475         /* parameters */
11476         if(po>offset){
11477                 /* We have some initial padding bytes.
11478                 */
11479                 padcnt = po-offset;
11480                 if (padcnt > bc)
11481                         padcnt = bc;
11482                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11483                 COUNT_BYTES(padcnt);
11484         }
11485         if(pc){
11486                 CHECK_BYTE_COUNT(pc);
11487                 switch(si->cmd) {
11488
11489                 case SMB_COM_TRANSACTION2:
11490                         /* TRANSACTION2 parameters*/
11491                         offset = dissect_transaction2_request_parameters(tvb,
11492                             pinfo, tree, offset, subcmd, pc);
11493                         bc -= pc;
11494                         break;
11495
11496                 case SMB_COM_TRANSACTION:
11497                         /* TRANSACTION parameters processed below */
11498                         COUNT_BYTES(pc);
11499                         break;
11500                 }
11501         }
11502
11503         /* data */
11504         if(od>offset){
11505                 /* We have some initial padding bytes.
11506                 */
11507                 padcnt = od-offset;
11508                 if (padcnt > bc)
11509                         padcnt = bc;
11510                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11511                 COUNT_BYTES(padcnt);
11512         }
11513         if(dc){
11514                 CHECK_BYTE_COUNT(dc);
11515                 switch(si->cmd){
11516
11517                 case SMB_COM_TRANSACTION2:
11518                         /* TRANSACTION2 data*/
11519                         offset = dissect_transaction2_request_data(tvb, pinfo,
11520                             tree, offset, subcmd, dc);
11521                         bc -= dc;
11522                         break;
11523
11524                 case SMB_COM_TRANSACTION:
11525                         /* TRANSACTION data processed below */
11526                         COUNT_BYTES(dc);
11527                         break;
11528                 }
11529         }
11530
11531         /*TRANSACTION request parameters */
11532         if(si->cmd==SMB_COM_TRANSACTION){
11533                 /*XXX replace this block with a function and use that one
11534                      for both requests/responses*/
11535                 if(dd==0){
11536                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
11537                         tvbuff_t *sp_tvb, *pd_tvb;
11538
11539                         if(pc>0){
11540                                 if(pc>tvb_length_remaining(tvb, po)){
11541                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
11542                                 } else {
11543                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
11544                                 }
11545                         } else {
11546                                 p_tvb = NULL;
11547                         }
11548                         if(dc>0){
11549                                 if(dc>tvb_length_remaining(tvb, od)){
11550                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
11551                                 } else {
11552                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
11553                                 }
11554                         } else {
11555                                 d_tvb = NULL;
11556                         }
11557                         if(sl){
11558                                 if(sl>tvb_length_remaining(tvb, so)){
11559                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
11560                                 } else {
11561                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
11562                                 }
11563                         } else {
11564                                 s_tvb = NULL;
11565                         }
11566
11567                         if (!si->unidir) {
11568                                 if(!pinfo->fd->flags.visited){
11569                                         /*
11570                                          * Allocate a new smb_transact_info_t
11571                                          * structure.
11572                                          */
11573                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
11574                                         tri->subcmd = -1;
11575                                         tri->trans_subcmd = -1;
11576                                         tri->function = -1;
11577                                         tri->fid = -1;
11578                                         tri->lanman_cmd = 0;
11579                                         tri->param_descrip = NULL;
11580                                         tri->data_descrip = NULL;
11581                                         tri->aux_data_descrip = NULL;
11582                                         tri->info_level = -1;
11583                                         si->sip->extra_info = tri;
11584                                 } else {
11585                                         /*
11586                                          * We already filled the structure
11587                                          * in; don't bother doing so again.
11588                                          */
11589                                         tri = NULL;
11590                                 }
11591                         } else {
11592                                 /*
11593                                  * This is a unidirectional message, for
11594                                  * which there will be no reply; don't
11595                                  * bother allocating an "smb_transact_info_t"
11596                                  * structure for it.
11597                                  */
11598                                 tri = NULL;
11599                         }
11600                         dissected_trans = FALSE;
11601                         if(strncmp("\\PIPE\\", an, 6) == 0){
11602                                 if (tri != NULL)
11603                                         tri->subcmd=TRANSACTION_PIPE;
11604
11605                                 /*
11606                                  * A tvbuff containing the setup words and
11607                                  * the pipe path.
11608                                  */
11609                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
11610
11611                                 /*
11612                                  * A tvbuff containing the parameters and the
11613                                  * data.
11614                                  */
11615                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
11616
11617                                 dissected_trans = dissect_pipe_smb(sp_tvb,
11618                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
11619                                     top_tree);
11620
11621                                 /* In case we did not see the TreeConnect call,
11622                                    store this TID here as well as a IPC TID 
11623                                    so we know that future Read/Writes to this 
11624                                    TID is (probably) DCERPC.
11625                                 */
11626                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
11627                                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
11628                                 }
11629                                 g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
11630                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
11631                                 if (tri != NULL)
11632                                         tri->subcmd=TRANSACTION_MAILSLOT;
11633
11634                                 /*
11635                                  * A tvbuff containing the setup words and
11636                                  * the mailslot path.
11637                                  */
11638                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
11639                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
11640                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
11641                         }
11642                         if (!dissected_trans)
11643                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
11644                 } else {
11645                         if(check_col(pinfo->cinfo, COL_INFO)){
11646                                 col_append_str(pinfo->cinfo, COL_INFO,
11647                                         "[transact continuation]");
11648                         }
11649                 }
11650         }
11651
11652         END_OF_SMB
11653
11654         return offset;
11655 }
11656
11657
11658
11659 static int
11660 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11661     int offset, guint16 *bcp, gboolean *trunc)
11662 {
11663         int fn_len;
11664         const char *fn;
11665         int old_offset = offset;
11666         proto_item *item = NULL;
11667         proto_tree *tree = NULL;
11668         smb_info_t *si;
11669         smb_transact2_info_t *t2i;
11670         gboolean resume_keys = FALSE;
11671
11672         si = (smb_info_t *)pinfo->private_data;
11673         if (si->sip != NULL) {
11674                 t2i = si->sip->extra_info;
11675                 if (t2i != NULL)
11676                         resume_keys = t2i->resume_keys;
11677         }
11678
11679         if(parent_tree){
11680                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11681                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11682                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11683         }
11684
11685         if (resume_keys) {
11686                 /* resume key */
11687                 CHECK_BYTE_COUNT_SUBR(4);
11688                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
11689                 COUNT_BYTES_SUBR(4);
11690         }
11691
11692         /* create time */
11693         CHECK_BYTE_COUNT_SUBR(4);
11694         offset = dissect_smb_datetime(tvb, tree, offset,
11695                 hf_smb_create_time,
11696                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
11697         *bcp -= 4;
11698
11699         /* access time */
11700         CHECK_BYTE_COUNT_SUBR(4);
11701         offset = dissect_smb_datetime(tvb, tree, offset,
11702                 hf_smb_access_time,
11703                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
11704         *bcp -= 4;
11705
11706         /* last write time */
11707         CHECK_BYTE_COUNT_SUBR(4);
11708         offset = dissect_smb_datetime(tvb, tree, offset,
11709                 hf_smb_last_write_time,
11710                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
11711         *bcp -= 4;
11712
11713         /* data size */
11714         CHECK_BYTE_COUNT_SUBR(4);
11715         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11716         COUNT_BYTES_SUBR(4);
11717
11718         /* allocation size */
11719         CHECK_BYTE_COUNT_SUBR(4);
11720         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
11721         COUNT_BYTES_SUBR(4);
11722
11723         /* File Attributes */
11724         CHECK_BYTE_COUNT_SUBR(2);
11725         offset = dissect_file_attributes(tvb, tree, offset, 2);
11726         *bcp -= 2;
11727
11728         /* file name len */
11729         CHECK_BYTE_COUNT_SUBR(1);
11730         fn_len = tvb_get_guint8(tvb, offset);
11731         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
11732         COUNT_BYTES_SUBR(1);
11733         if (si->unicode)
11734                 fn_len += 2;    /* include terminating '\0' */
11735         else
11736                 fn_len++;       /* include terminating '\0' */
11737
11738         /* file name */
11739         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11740         CHECK_STRING_SUBR(fn);
11741         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11742                 fn);
11743         COUNT_BYTES_SUBR(fn_len);
11744
11745         if (check_col(pinfo->cinfo, COL_INFO)) {
11746                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11747                 fn);
11748         }
11749
11750         proto_item_append_text(item, " File: %s", fn);
11751         proto_item_set_len(item, offset-old_offset);
11752
11753         *trunc = FALSE;
11754         return offset;
11755 }
11756
11757 static int
11758 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11759     int offset, guint16 *bcp, gboolean *trunc)
11760 {
11761         int fn_len;
11762         const char *fn;
11763         int old_offset = offset;
11764         proto_item *item = NULL;
11765         proto_tree *tree = NULL;
11766         smb_info_t *si;
11767         smb_transact2_info_t *t2i;
11768         gboolean resume_keys = FALSE;
11769
11770         si = (smb_info_t *)pinfo->private_data;
11771         if (si->sip != NULL) {
11772                 t2i = si->sip->extra_info;
11773                 if (t2i != NULL)
11774                         resume_keys = t2i->resume_keys;
11775         }
11776
11777         if(parent_tree){
11778                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11779                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11780                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11781         }
11782
11783         if (resume_keys) {
11784                 /* resume key */
11785                 CHECK_BYTE_COUNT_SUBR(4);
11786                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
11787                 COUNT_BYTES_SUBR(4);
11788         }
11789
11790         /* create time */
11791         CHECK_BYTE_COUNT_SUBR(4);
11792         offset = dissect_smb_datetime(tvb, tree, offset,
11793                 hf_smb_create_time,
11794                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
11795         *bcp -= 4;
11796
11797         /* access time */
11798         CHECK_BYTE_COUNT_SUBR(4);
11799         offset = dissect_smb_datetime(tvb, tree, offset,
11800                 hf_smb_access_time,
11801                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
11802         *bcp -= 4;
11803
11804         /* last write time */
11805         CHECK_BYTE_COUNT_SUBR(4);
11806         offset = dissect_smb_datetime(tvb, tree, offset,
11807                 hf_smb_last_write_time,
11808                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
11809         *bcp -= 4;
11810
11811         /* data size */
11812         CHECK_BYTE_COUNT_SUBR(4);
11813         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11814         COUNT_BYTES_SUBR(4);
11815
11816         /* allocation size */
11817         CHECK_BYTE_COUNT_SUBR(4);
11818         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
11819         COUNT_BYTES_SUBR(4);
11820
11821         /* File Attributes */
11822         CHECK_BYTE_COUNT_SUBR(2);
11823         offset = dissect_file_attributes(tvb, tree, offset, 2);
11824         *bcp -= 2;
11825
11826         /* ea size */
11827         CHECK_BYTE_COUNT_SUBR(4);
11828         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
11829         COUNT_BYTES_SUBR(4);
11830
11831         /* file name len */
11832         CHECK_BYTE_COUNT_SUBR(1);
11833         fn_len = tvb_get_guint8(tvb, offset);
11834         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
11835         COUNT_BYTES_SUBR(1);
11836
11837         /* file name */
11838         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11839         CHECK_STRING_SUBR(fn);
11840         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11841                 fn);
11842         COUNT_BYTES_SUBR(fn_len);
11843         if (si->unicode)
11844                 fn_len += 2;    /* include terminating '\0' */
11845         else
11846                 fn_len++;       /* include terminating '\0' */
11847
11848         if (check_col(pinfo->cinfo, COL_INFO)) {
11849                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11850                 fn);
11851         }
11852
11853         proto_item_append_text(item, " File: %s", fn);
11854         proto_item_set_len(item, offset-old_offset);
11855
11856         *trunc = FALSE;
11857         return offset;
11858 }
11859
11860 static int
11861 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11862     int offset, guint16 *bcp, gboolean *trunc)
11863 {
11864         int fn_len;
11865         const char *fn;
11866         int old_offset = offset;
11867         proto_item *item = NULL;
11868         proto_tree *tree = NULL;
11869         smb_info_t *si;
11870         guint32 neo;
11871         int padcnt;
11872
11873         si = (smb_info_t *)pinfo->private_data;
11874
11875         if(parent_tree){
11876                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11877                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11878                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11879         }
11880
11881         /*
11882          * We assume that the presence of a next entry offset implies the
11883          * absence of a resume key, as appears to be the case for 4.3.4.6.
11884          */
11885
11886         /* next entry offset */
11887         CHECK_BYTE_COUNT_SUBR(4);
11888         neo = tvb_get_letohl(tvb, offset);
11889         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11890         COUNT_BYTES_SUBR(4);
11891
11892         /* file index */
11893         CHECK_BYTE_COUNT_SUBR(4);
11894         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11895         COUNT_BYTES_SUBR(4);
11896
11897         /* create time */
11898         CHECK_BYTE_COUNT_SUBR(8);
11899         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
11900         *bcp -= 8;
11901
11902         /* access time */
11903         CHECK_BYTE_COUNT_SUBR(8);
11904         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
11905         *bcp -= 8;
11906
11907         /* last write time */
11908         CHECK_BYTE_COUNT_SUBR(8);
11909         offset = dissect_smb_64bit_time(tvb, tree, offset,
11910                 hf_smb_last_write_time);
11911         *bcp -= 8;
11912
11913         /* last change time */
11914         CHECK_BYTE_COUNT_SUBR(8);
11915         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
11916         *bcp -= 8;
11917
11918         /* end of file */
11919         CHECK_BYTE_COUNT_SUBR(8);
11920         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11921         COUNT_BYTES_SUBR(8);
11922
11923         /* allocation size */
11924         CHECK_BYTE_COUNT_SUBR(8);
11925         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11926         COUNT_BYTES_SUBR(8);
11927
11928         /* Extended File Attributes */
11929         CHECK_BYTE_COUNT_SUBR(4);
11930         offset = dissect_file_ext_attr(tvb, tree, offset);
11931         *bcp -= 4;
11932
11933         /* file name len */
11934         CHECK_BYTE_COUNT_SUBR(4);
11935         fn_len = tvb_get_letohl(tvb, offset);
11936         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11937         COUNT_BYTES_SUBR(4);
11938
11939         /* file name */
11940         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11941         CHECK_STRING_SUBR(fn);
11942         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11943                 fn);
11944         COUNT_BYTES_SUBR(fn_len);
11945
11946         if (check_col(pinfo->cinfo, COL_INFO)) {
11947                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11948                 fn);
11949         }
11950
11951         /* skip to next structure */
11952         if(neo){
11953                 padcnt = (old_offset + neo) - offset;
11954                 if (padcnt < 0) {
11955                         /*
11956                          * XXX - this is bogus; flag it?
11957                          */
11958                         padcnt = 0;
11959                 }
11960                 if (padcnt != 0) {
11961                         CHECK_BYTE_COUNT_SUBR(padcnt);
11962                         COUNT_BYTES_SUBR(padcnt);
11963                 }
11964         }
11965
11966         proto_item_append_text(item, " File: %s", fn);
11967         proto_item_set_len(item, offset-old_offset);
11968
11969         *trunc = FALSE;
11970         return offset;
11971 }
11972
11973 static int
11974 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11975     int offset, guint16 *bcp, gboolean *trunc)
11976 {
11977         int fn_len;
11978         const char *fn;
11979         int old_offset = offset;
11980         proto_item *item = NULL;
11981         proto_tree *tree = NULL;
11982         smb_info_t *si;
11983         guint32 neo;
11984         int padcnt;
11985
11986         si = (smb_info_t *)pinfo->private_data;
11987
11988         if(parent_tree){
11989                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11990                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11991                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11992         }
11993
11994         /*
11995          * We assume that the presence of a next entry offset implies the
11996          * absence of a resume key, as appears to be the case for 4.3.4.6.
11997          */
11998
11999         /* next entry offset */
12000         CHECK_BYTE_COUNT_SUBR(4);
12001         neo = tvb_get_letohl(tvb, offset);
12002         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12003         COUNT_BYTES_SUBR(4);
12004
12005         /* file index */
12006         CHECK_BYTE_COUNT_SUBR(4);
12007         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12008         COUNT_BYTES_SUBR(4);
12009
12010         /* create time */
12011         CHECK_BYTE_COUNT_SUBR(8);
12012         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12013         *bcp -= 8;
12014
12015         /* access time */
12016         CHECK_BYTE_COUNT_SUBR(8);
12017         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12018         *bcp -= 8;
12019
12020         /* last write time */
12021         CHECK_BYTE_COUNT_SUBR(8);
12022         offset = dissect_smb_64bit_time(tvb, tree, offset,
12023                 hf_smb_last_write_time);
12024         *bcp -= 8;
12025
12026         /* last change time */
12027         CHECK_BYTE_COUNT_SUBR(8);
12028         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12029         *bcp -= 8;
12030
12031         /* end of file */
12032         CHECK_BYTE_COUNT_SUBR(8);
12033         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12034         COUNT_BYTES_SUBR(8);
12035
12036         /* allocation size */
12037         CHECK_BYTE_COUNT_SUBR(8);
12038         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12039         COUNT_BYTES_SUBR(8);
12040
12041         /* Extended File Attributes */
12042         CHECK_BYTE_COUNT_SUBR(4);
12043         offset = dissect_file_ext_attr(tvb, tree, offset);
12044         *bcp -= 4;
12045
12046         /* file name len */
12047         CHECK_BYTE_COUNT_SUBR(4);
12048         fn_len = tvb_get_letohl(tvb, offset);
12049         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12050         COUNT_BYTES_SUBR(4);
12051
12052         /* ea size */
12053         CHECK_BYTE_COUNT_SUBR(4);
12054         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
12055         COUNT_BYTES_SUBR(4);
12056
12057         /* file name */
12058         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12059         CHECK_STRING_SUBR(fn);
12060         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12061                 fn);
12062         COUNT_BYTES_SUBR(fn_len);
12063
12064         if (check_col(pinfo->cinfo, COL_INFO)) {
12065                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12066                 fn);
12067         }
12068
12069         /* skip to next structure */
12070         if(neo){
12071                 padcnt = (old_offset + neo) - offset;
12072                 if (padcnt < 0) {
12073                         /*
12074                          * XXX - this is bogus; flag it?
12075                          */
12076                         padcnt = 0;
12077                 }
12078                 if (padcnt != 0) {
12079                         CHECK_BYTE_COUNT_SUBR(padcnt);
12080                         COUNT_BYTES_SUBR(padcnt);
12081                 }
12082         }
12083
12084         proto_item_append_text(item, " File: %s", fn);
12085         proto_item_set_len(item, offset-old_offset);
12086
12087         *trunc = FALSE;
12088         return offset;
12089 }
12090
12091 static int
12092 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12093     int offset, guint16 *bcp, gboolean *trunc)
12094 {
12095         int fn_len, sfn_len;
12096         const char *fn, *sfn;
12097         int old_offset = offset;
12098         proto_item *item = NULL;
12099         proto_tree *tree = NULL;
12100         smb_info_t *si;
12101         guint32 neo;
12102         int padcnt;
12103
12104         si = (smb_info_t *)pinfo->private_data;
12105
12106         if(parent_tree){
12107                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12108                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12109                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12110         }
12111
12112         /*
12113          * XXX - I have not seen any of these that contain a resume
12114          * key, even though some of the requests had the "return resume
12115          * key" flag set.
12116          */
12117
12118         /* next entry offset */
12119         CHECK_BYTE_COUNT_SUBR(4);
12120         neo = tvb_get_letohl(tvb, offset);
12121         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12122         COUNT_BYTES_SUBR(4);
12123
12124         /* file index */
12125         CHECK_BYTE_COUNT_SUBR(4);
12126         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12127         COUNT_BYTES_SUBR(4);
12128
12129         /* create time */
12130         CHECK_BYTE_COUNT_SUBR(8);
12131         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12132         *bcp -= 8;
12133
12134         /* access time */
12135         CHECK_BYTE_COUNT_SUBR(8);
12136         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12137         *bcp -= 8;
12138
12139         /* last write time */
12140         CHECK_BYTE_COUNT_SUBR(8);
12141         offset = dissect_smb_64bit_time(tvb, tree, offset,
12142                 hf_smb_last_write_time);
12143         *bcp -= 8;
12144
12145         /* last change time */
12146         CHECK_BYTE_COUNT_SUBR(8);
12147         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12148         *bcp -= 8;
12149
12150         /* end of file */
12151         CHECK_BYTE_COUNT_SUBR(8);
12152         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12153         COUNT_BYTES_SUBR(8);
12154
12155         /* allocation size */
12156         CHECK_BYTE_COUNT_SUBR(8);
12157         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12158         COUNT_BYTES_SUBR(8);
12159
12160         /* Extended File Attributes */
12161         CHECK_BYTE_COUNT_SUBR(4);
12162         offset = dissect_file_ext_attr(tvb, tree, offset);
12163         *bcp -= 4;
12164
12165         /* file name len */
12166         CHECK_BYTE_COUNT_SUBR(4);
12167         fn_len = tvb_get_letohl(tvb, offset);
12168         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12169         COUNT_BYTES_SUBR(4);
12170
12171         /* ea size */
12172         CHECK_BYTE_COUNT_SUBR(4);
12173         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
12174         COUNT_BYTES_SUBR(4);
12175
12176         /* short file name len */
12177         CHECK_BYTE_COUNT_SUBR(1);
12178         sfn_len = tvb_get_guint8(tvb, offset);
12179         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
12180         COUNT_BYTES_SUBR(1);
12181
12182         /* reserved byte */
12183         CHECK_BYTE_COUNT_SUBR(1);
12184         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12185         COUNT_BYTES_SUBR(1);
12186
12187         /* short file name */
12188         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
12189         CHECK_STRING_SUBR(sfn);
12190         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
12191                 sfn);
12192         COUNT_BYTES_SUBR(24);
12193
12194         /* file name */
12195         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12196         CHECK_STRING_SUBR(fn);
12197         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12198                 fn);
12199         COUNT_BYTES_SUBR(fn_len);
12200
12201         if (check_col(pinfo->cinfo, COL_INFO)) {
12202                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12203                 fn);
12204         }
12205
12206         /* skip to next structure */
12207         if(neo){
12208                 padcnt = (old_offset + neo) - offset;
12209                 if (padcnt < 0) {
12210                         /*
12211                          * XXX - this is bogus; flag it?
12212                          */
12213                         padcnt = 0;
12214                 }
12215                 if (padcnt != 0) {
12216                         CHECK_BYTE_COUNT_SUBR(padcnt);
12217                         COUNT_BYTES_SUBR(padcnt);
12218                 }
12219         }
12220
12221         proto_item_append_text(item, " File: %s", fn);
12222         proto_item_set_len(item, offset-old_offset);
12223
12224         *trunc = FALSE;
12225         return offset;
12226 }
12227
12228 static int
12229 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12230     int offset, guint16 *bcp, gboolean *trunc)
12231 {
12232         int fn_len;
12233         const char *fn;
12234         int old_offset = offset;
12235         proto_item *item = NULL;
12236         proto_tree *tree = NULL;
12237         smb_info_t *si;
12238         guint32 neo;
12239         int padcnt;
12240
12241         si = (smb_info_t *)pinfo->private_data;
12242
12243         if(parent_tree){
12244                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12245                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12246                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12247         }
12248
12249         /*
12250          * We assume that the presence of a next entry offset implies the
12251          * absence of a resume key, as appears to be the case for 4.3.4.6.
12252          */
12253
12254         /* next entry offset */
12255         CHECK_BYTE_COUNT_SUBR(4);
12256         neo = tvb_get_letohl(tvb, offset);
12257         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12258         COUNT_BYTES_SUBR(4);
12259
12260         /* file index */
12261         CHECK_BYTE_COUNT_SUBR(4);
12262         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12263         COUNT_BYTES_SUBR(4);
12264
12265         /* file name len */
12266         CHECK_BYTE_COUNT_SUBR(4);
12267         fn_len = tvb_get_letohl(tvb, offset);
12268         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12269         COUNT_BYTES_SUBR(4);
12270
12271         /* file name */
12272         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12273         CHECK_STRING_SUBR(fn);
12274         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12275                 fn);
12276         COUNT_BYTES_SUBR(fn_len);
12277
12278         if (check_col(pinfo->cinfo, COL_INFO)) {
12279                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12280                 fn);
12281         }
12282
12283         /* skip to next structure */
12284         if(neo){
12285                 padcnt = (old_offset + neo) - offset;
12286                 if (padcnt < 0) {
12287                         /*
12288                          * XXX - this is bogus; flag it?
12289                          */
12290                         padcnt = 0;
12291                 }
12292                 if (padcnt != 0) {
12293                         CHECK_BYTE_COUNT_SUBR(padcnt);
12294                         COUNT_BYTES_SUBR(padcnt);
12295                 }
12296         }
12297
12298         proto_item_append_text(item, " File: %s", fn);
12299         proto_item_set_len(item, offset-old_offset);
12300
12301         *trunc = FALSE;
12302         return offset;
12303 }
12304
12305 static int
12306 dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
12307                 proto_tree *parent_tree _U_, int offset, guint16 *bcp,
12308                 gboolean *trunc)
12309 {
12310 /*XXX im lazy. i havnt implemented this */
12311         offset += *bcp;
12312         *bcp = 0;
12313         *trunc = FALSE;
12314         return offset;
12315 }
12316
12317 /*dissect the data block for TRANS2_FIND_FIRST2*/
12318 static int
12319 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
12320     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
12321 {
12322         smb_info_t *si;
12323
12324         if(!*bcp){
12325                 return offset;
12326         }
12327
12328         si = (smb_info_t *)pinfo->private_data;
12329         switch(si->info_level){
12330         case 1:         /*Info Standard*/
12331                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
12332                     trunc);
12333                 break;
12334         case 2:         /*Info Query EA Size*/
12335                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
12336                     trunc);
12337                 break;
12338         case 3:         /*Info Query EAs From List same as
12339                                 InfoQueryEASize*/
12340                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
12341                     trunc);
12342                 break;
12343         case 0x0101:    /*Find File Directory Info*/
12344                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
12345                     trunc);
12346                 break;
12347         case 0x0102:    /*Find File Full Directory Info*/
12348                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
12349                     trunc);
12350                 break;
12351         case 0x0103:    /*Find File Names Info*/
12352                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
12353                     trunc);
12354                 break;
12355         case 0x0104:    /*Find File Both Directory Info*/
12356                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
12357                     trunc);
12358                 break;
12359         case 0x0202:    /*Find File UNIX*/
12360                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
12361                     trunc);
12362                 break;
12363         default:        /* unknown info level */
12364                 *trunc = FALSE;
12365                 break;
12366         }
12367         return offset;
12368 }
12369
12370
12371 static int
12372 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12373 {
12374         guint32 mask;
12375         proto_item *item = NULL;
12376         proto_tree *tree = NULL;
12377
12378         mask = tvb_get_letohl(tvb, offset);
12379
12380         if(parent_tree){
12381                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
12382                         "FS Attributes: 0x%08x", mask);
12383                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
12384         }
12385
12386         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
12387                 tvb, offset, 4, mask);
12388         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
12389                 tvb, offset, 4, mask);
12390         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
12391                 tvb, offset, 4, mask);
12392         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
12393                 tvb, offset, 4, mask);
12394         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
12395                 tvb, offset, 4, mask);
12396         proto_tree_add_boolean(tree, hf_smb_fs_attr_dim,
12397                 tvb, offset, 4, mask);
12398         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
12399                 tvb, offset, 4, mask);
12400
12401         offset += 4;
12402         return offset;
12403 }
12404
12405
12406 static int
12407 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12408 {
12409         guint32 mask;
12410         proto_item *item = NULL;
12411         proto_tree *tree = NULL;
12412
12413         mask = tvb_get_letohl(tvb, offset);
12414
12415         if(parent_tree){
12416                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
12417                         "Device Characteristics: 0x%08x", mask);
12418                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
12419         }
12420
12421         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
12422                 tvb, offset, 4, mask);
12423         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
12424                 tvb, offset, 4, mask);
12425         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
12426                 tvb, offset, 4, mask);
12427         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
12428                 tvb, offset, 4, mask);
12429         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
12430                 tvb, offset, 4, mask);
12431         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
12432                 tvb, offset, 4, mask);
12433         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
12434                 tvb, offset, 4, mask);
12435
12436         offset += 4;
12437         return offset;
12438 }
12439
12440 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
12441
12442 static const true_false_string tfs_smb_mac_access_ctrl = {
12443   "Macintosh Access Control Supported",
12444   "Macintosh Access Control Not Supported"
12445 };
12446
12447 static const true_false_string tfs_smb_mac_getset_comments = {
12448   "Macintosh Get & Set Comments Supported",
12449   "Macintosh Get & Set Comments Not Supported"
12450 };
12451
12452 static const true_false_string tfs_smb_mac_desktopdb_calls = {
12453   "Macintosh Get & Set Desktop Database Info Supported",
12454   "Macintosh Get & Set Desktop Database Info Supported"
12455 };
12456
12457 static const true_false_string tfs_smb_mac_unique_ids = {
12458   "Macintosh Unique IDs Supported",
12459   "Macintosh Unique IDs Not Supported"
12460 };
12461
12462 static const true_false_string tfs_smb_mac_streams = {
12463   "Macintosh and Streams Extensions Not Supported",
12464   "Macintosh and Streams Extensions Supported"
12465 };
12466
12467 static int
12468 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
12469     int offset, guint16 *bcp)
12470 {
12471         smb_info_t *si;
12472         int fn_len, vll, fnl;
12473         const char *fn;
12474         guint support = 0;
12475         proto_item *item = NULL;
12476         proto_tree *ti = NULL;
12477
12478         if(!*bcp){
12479                 return offset;
12480         }
12481
12482         si = (smb_info_t *)pinfo->private_data;
12483         switch(si->info_level){
12484         case 1:         /* SMB_INFO_ALLOCATION */
12485                 /* filesystem id */
12486                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12487                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
12488                 COUNT_BYTES_TRANS_SUBR(4);
12489
12490                 /* sectors per unit */
12491                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12492                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12493                 COUNT_BYTES_TRANS_SUBR(4);
12494
12495                 /* units */
12496                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12497                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
12498                 COUNT_BYTES_TRANS_SUBR(4);
12499
12500                 /* avail units */
12501                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12502                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
12503                 COUNT_BYTES_TRANS_SUBR(4);
12504
12505                 /* bytes per sector, only 16bit integer here */
12506                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
12507                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12508                 COUNT_BYTES_TRANS_SUBR(2);
12509
12510                 break;
12511         case 2:         /* SMB_INFO_VOLUME */
12512                 /* volume serial number */
12513                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12514                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
12515                 COUNT_BYTES_TRANS_SUBR(4);
12516
12517                 /* volume label length, only one byte here */
12518                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
12519                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
12520                 COUNT_BYTES_TRANS_SUBR(1);
12521
12522                 /* label */
12523                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
12524                 CHECK_STRING_TRANS_SUBR(fn);
12525                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12526                         fn);
12527                 COUNT_BYTES_TRANS_SUBR(fn_len);
12528
12529                 break;
12530         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
12531         case 1001:      /* SMB_FS_LABEL_INFORMATION */
12532                 /* volume label length */
12533                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12534                 vll = tvb_get_letohl(tvb, offset);
12535                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
12536                 COUNT_BYTES_TRANS_SUBR(4);
12537
12538                 /* label */
12539                 fn_len = vll;
12540                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12541                 CHECK_STRING_TRANS_SUBR(fn);
12542                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12543                         fn);
12544                 COUNT_BYTES_TRANS_SUBR(fn_len);
12545
12546                 break;
12547         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
12548         case 1002:      /* SMB_FS_VOLUME_INFORMATION */
12549                 /* create time */
12550                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12551                 offset = dissect_smb_64bit_time(tvb, tree, offset,
12552                         hf_smb_create_time);
12553                 *bcp -= 8;
12554
12555                 /* volume serial number */
12556                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12557                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
12558                 COUNT_BYTES_TRANS_SUBR(4);
12559
12560                 /* volume label length */
12561                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12562                 vll = tvb_get_letohl(tvb, offset);
12563                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
12564                 COUNT_BYTES_TRANS_SUBR(4);
12565
12566                 /* 2 reserved bytes */
12567                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
12568                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
12569                 COUNT_BYTES_TRANS_SUBR(2);
12570
12571                 /* label */
12572                 fn_len = vll;
12573                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12574                 CHECK_STRING_TRANS_SUBR(fn);
12575                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12576                         fn);
12577                 COUNT_BYTES_TRANS_SUBR(fn_len);
12578
12579                 break;
12580         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
12581         case 1003:      /* SMB_FS_SIZE_INFORMATION */
12582                 /* allocation size */
12583                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12584                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12585                 COUNT_BYTES_TRANS_SUBR(8);
12586
12587                 /* free allocation units */
12588                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12589                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
12590                 COUNT_BYTES_TRANS_SUBR(8);
12591
12592                 /* sectors per unit */
12593                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12594                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12595                 COUNT_BYTES_TRANS_SUBR(4);
12596
12597                 /* bytes per sector */
12598                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12599                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
12600                 COUNT_BYTES_TRANS_SUBR(4);
12601
12602                 break;
12603         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
12604         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
12605                 /* device type */
12606                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12607                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
12608                 COUNT_BYTES_TRANS_SUBR(4);
12609
12610                 /* device characteristics */
12611                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12612                 offset = dissect_device_characteristics(tvb, tree, offset);
12613                 *bcp -= 4;
12614
12615                 break;
12616         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
12617         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
12618                 /* FS attributes */
12619                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12620                 offset = dissect_fs_attributes(tvb, tree, offset);
12621                 *bcp -= 4;
12622
12623                 /* max name len */
12624                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12625                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
12626                 COUNT_BYTES_TRANS_SUBR(4);
12627
12628                 /* fs name length */
12629                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12630                 fnl = tvb_get_letohl(tvb, offset);
12631                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
12632                 COUNT_BYTES_TRANS_SUBR(4);
12633
12634                 /* label */
12635                 fn_len = fnl;
12636                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12637                 CHECK_STRING_TRANS_SUBR(fn);
12638                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
12639                         fn);
12640                 COUNT_BYTES_TRANS_SUBR(fn_len);
12641
12642                 break;
12643         case 0x301:     /* MAC_QUERY_FS_INFO */
12644                 /* Create time */
12645                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12646                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12647                 *bcp -= 8;
12648                 /* Modify Time */
12649                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12650                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_modify_time);
12651                 *bcp -= 8;
12652                 /* Backup Time */
12653                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12654                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_backup_time);
12655                 *bcp -= 8;
12656                 /* Allocation blocks */
12657                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12658                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
12659                                     offset,
12660                                     4, TRUE);
12661                 COUNT_BYTES_TRANS_SUBR(4);
12662                 /* Allocation Block Size */
12663                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12664                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
12665                                     offset, 4, TRUE);
12666                 COUNT_BYTES_TRANS_SUBR(4);
12667                 /* Free Block Count */
12668                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12669                 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
12670                                     offset, 4, TRUE);
12671                 COUNT_BYTES_TRANS_SUBR(4);
12672                 /* Finder Info ... */
12673                 CHECK_BYTE_COUNT_TRANS_SUBR(32);
12674                 proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb,
12675                                             offset, 32,
12676                                             tvb_get_ptr(tvb, offset,32),
12677                                             "Finder Info: %s",
12678                                             tvb_format_text(tvb, offset, 32));
12679                 COUNT_BYTES_TRANS_SUBR(32);
12680                 /* Number Files */
12681                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12682                 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
12683                                     offset, 4, TRUE);
12684                 COUNT_BYTES_TRANS_SUBR(4);
12685                 /* Number of Root Directories */
12686                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12687                 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
12688                                     offset, 4, TRUE);
12689                 COUNT_BYTES_TRANS_SUBR(4);
12690                 /* Number of files */
12691                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12692                 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
12693                                     offset, 4, TRUE);
12694                 COUNT_BYTES_TRANS_SUBR(4);
12695                 /* Dir Count */
12696                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12697                 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
12698                                     offset, 4, TRUE);
12699                 COUNT_BYTES_TRANS_SUBR(4);
12700                 /* Mac Support Flags */
12701                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12702                 support = tvb_get_ntohl(tvb, offset);
12703                 item = proto_tree_add_text(tree, tvb, offset, 4,
12704                                            "Mac Support Flags: 0x%08x", support);
12705                 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
12706                 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
12707                                        tvb, offset, 4, support);
12708                 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
12709                                        tvb, offset, 4, support);
12710                 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
12711                                        tvb, offset, 4, support);
12712                 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
12713                                        tvb, offset, 4, support);
12714                 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
12715                                        tvb, offset, 4, support);
12716                 COUNT_BYTES_TRANS_SUBR(4);
12717                 break;
12718         case 1006:      /* QUERY_FS_QUOTA_INFO */
12719                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
12720                 break;
12721         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
12722                 /* allocation size */
12723                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12724                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12725                 COUNT_BYTES_TRANS_SUBR(8);
12726
12727                 /* caller free allocation units */
12728                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12729                 proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
12730                 COUNT_BYTES_TRANS_SUBR(8);
12731
12732                 /* actual free allocation units */
12733                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12734                 proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
12735                 COUNT_BYTES_TRANS_SUBR(8);
12736
12737                 /* sectors per unit */
12738                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12739                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12740                 COUNT_BYTES_TRANS_SUBR(4);
12741
12742                 /* bytes per sector */
12743                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12744                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
12745                 COUNT_BYTES_TRANS_SUBR(4);
12746                 break;
12747         }
12748
12749         return offset;
12750 }
12751
12752 static int
12753 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
12754     proto_tree *parent_tree)
12755 {
12756         proto_item *item = NULL;
12757         proto_tree *tree = NULL;
12758         smb_info_t *si;
12759         smb_transact2_info_t *t2i;
12760         int count;
12761         gboolean trunc;
12762         int offset = 0;
12763         guint16 dc;
12764
12765         dc = tvb_reported_length(tvb);
12766
12767         si = (smb_info_t *)pinfo->private_data;
12768         if (si->sip != NULL)
12769                 t2i = si->sip->extra_info;
12770         else
12771                 t2i = NULL;
12772
12773         if(parent_tree){
12774                 if (t2i != NULL && t2i->subcmd != -1) {
12775                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
12776                                 "%s Data",
12777                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
12778                                         "Unknown (0x%02x)"));
12779                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
12780                 } else {
12781                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
12782                                 "Unknown Transaction2 Data");
12783                 }
12784         }
12785
12786         if (t2i == NULL) {
12787                 offset += dc;
12788                 return offset;
12789         }
12790         switch(t2i->subcmd){
12791         case 0x00:      /*TRANS2_OPEN2*/
12792                 /* XXX not implemented yet. See SNIA doc */
12793                 break;
12794         case 0x01:      /*TRANS2_FIND_FIRST2*/
12795                 /* returned data */
12796                 count = si->info_count;
12797
12798                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
12799                         col_append_fstr(pinfo->cinfo, COL_INFO,
12800                         ", Files:");
12801                 }
12802
12803                 while(count--){
12804                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
12805                                 offset, &dc, &trunc);
12806                         if (trunc)
12807                                 break;
12808                 }
12809                 break;
12810         case 0x02:      /*TRANS2_FIND_NEXT2*/
12811                 /* returned data */
12812                 count = si->info_count;
12813
12814                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
12815                         col_append_fstr(pinfo->cinfo, COL_INFO,
12816                         ", Files:");
12817                 }
12818
12819                 while(count--){
12820                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
12821                                 offset, &dc, &trunc);
12822                         if (trunc)
12823                                 break;
12824                 }
12825                 break;
12826         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
12827                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
12828                 break;
12829         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
12830                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
12831                 break;
12832         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
12833                 /* no data in this response */
12834                 break;
12835         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
12836                 /* identical to QUERY_PATH_INFO */
12837                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
12838                 break;
12839         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
12840                 /* no data in this response */
12841                 break;
12842         case 0x09:      /*TRANS2_FSCTL*/
12843                 /* XXX dont know how to dissect this one (yet)*/
12844
12845                 /*
12846                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12847                  * Extensions Version 3.0, Document Version 1.11,
12848                  * July 19, 1990" says this this contains a
12849                  * "File system specific return data block".
12850                  * (That means we may not be able to dissect it in any
12851                  * case.)
12852                  */
12853                 break;
12854         case 0x0a:      /*TRANS2_IOCTL2*/
12855                 /* XXX dont know how to dissect this one (yet)*/
12856
12857                 /*
12858                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12859                  * Extensions Version 3.0, Document Version 1.11,
12860                  * July 19, 1990" says this this contains a
12861                  * "Device/function specific return data block".
12862                  * (That means we may not be able to dissect it in any
12863                  * case.)
12864                  */
12865                 break;
12866         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
12867                 /* XXX dont know how to dissect this one (yet)*/
12868
12869                 /*
12870                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12871                  * Extensions Version 3.0, Document Version 1.11,
12872                  * July 19, 1990" says this this contains "the level
12873                  * dependent information about the changes which
12874                  * occurred".
12875                  */
12876                 break;
12877         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
12878                 /* XXX dont know how to dissect this one (yet)*/
12879
12880                 /*
12881                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12882                  * Extensions Version 3.0, Document Version 1.11,
12883                  * July 19, 1990" says this this contains "the level
12884                  * dependent information about the changes which
12885                  * occurred".
12886                  */
12887                 break;
12888         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
12889                 /* no data in this response */
12890                 break;
12891         case 0x0e:      /*TRANS2_SESSION_SETUP*/
12892                 /* XXX dont know how to dissect this one (yet)*/
12893                 break;
12894         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
12895                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
12896                 break;
12897         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
12898                 /* the SNIA spec appears to say the response has no data */
12899                 break;
12900         case -1:
12901                 /*
12902                  * We don't know what the matching request was; don't
12903                  * bother putting anything else into the tree for the data.
12904                  */
12905                 offset += dc;
12906                 dc = 0;
12907                 break;
12908         }
12909
12910         /* ooops there were data we didnt know how to process */
12911         if(dc != 0){
12912                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
12913                 offset += dc;
12914         }
12915
12916         return offset;
12917 }
12918
12919
12920 static void
12921 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
12922 {
12923         proto_item *item = NULL;
12924         proto_tree *tree = NULL;
12925         smb_info_t *si;
12926         smb_transact2_info_t *t2i;
12927         guint16 fid;
12928         int lno;
12929         int offset = 0;
12930         int pc;
12931
12932         pc = tvb_reported_length(tvb);
12933
12934         si = (smb_info_t *)pinfo->private_data;
12935         if (si->sip != NULL)
12936                 t2i = si->sip->extra_info;
12937         else
12938                 t2i = NULL;
12939
12940         if(parent_tree){
12941                 if (t2i != NULL && t2i->subcmd != -1) {
12942                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
12943                                 "%s Parameters",
12944                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
12945                                                 "Unknown (0x%02x)"));
12946                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
12947                 } else {
12948                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
12949                                 "Unknown Transaction2 Parameters");
12950                 }
12951         }
12952
12953         if (t2i == NULL) {
12954                 offset += pc;
12955                 return;
12956         }
12957         switch(t2i->subcmd){
12958         case 0x00:      /*TRANS2_OPEN2*/
12959                 /* fid */
12960                 fid = tvb_get_letohs(tvb, offset);
12961                 add_fid(tvb, pinfo, tree, offset, 2, fid);
12962                 offset += 2;
12963
12964                 /*
12965                  * XXX - Microsoft Networks SMB File Sharing Protocol
12966                  * Extensions Version 3.0, Document Version 1.11,
12967                  * July 19, 1990 says that the file attributes, create
12968                  * time (which it says is the last modification time),
12969                  * data size, granted access, file type, and IPC state
12970                  * are returned only if bit 0 is set in the open flags,
12971                  * and that the EA length is returned only if bit 3
12972                  * is set in the open flags.  Does that mean that,
12973                  * at least in that SMB dialect, those fields are not
12974                  * present in the reply parameters if the bits in
12975                  * question aren't set?
12976                  */
12977
12978                 /* File Attributes */
12979                 offset = dissect_file_attributes(tvb, tree, offset, 2);
12980
12981                 /* create time */
12982                 offset = dissect_smb_datetime(tvb, tree, offset,
12983                         hf_smb_create_time,
12984                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
12985
12986                 /* data size */
12987                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12988                 offset += 4;
12989
12990                 /* granted access */
12991                 offset = dissect_access(tvb, tree, offset, "Granted");
12992
12993                 /* File Type */
12994                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
12995                 offset += 2;
12996
12997                 /* IPC State */
12998                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
12999
13000                 /* open_action */
13001                 offset = dissect_open_action(tvb, tree, offset);
13002
13003                 /* server unique file ID */
13004                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
13005                 offset += 4;
13006
13007                 /* ea error offset, only a 16 bit integer here */
13008                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13009                 offset += 2;
13010
13011                 /* ea length */
13012                 proto_tree_add_item(tree, hf_smb_ea_length, tvb, offset, 4, TRUE);
13013                 offset += 4;
13014
13015                 break;
13016         case 0x01:      /*TRANS2_FIND_FIRST2*/
13017                 /* Find First2 information level */
13018                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
13019
13020                 /* sid */
13021                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
13022                 offset += 2;
13023
13024                 /* search count */
13025                 si->info_count = tvb_get_letohs(tvb, offset);
13026                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13027                 offset += 2;
13028
13029                 /* end of search */
13030                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13031                 offset += 2;
13032
13033                 /* ea error offset, only a 16 bit integer here */
13034                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13035                 offset += 2;
13036
13037                 /* last name offset */
13038                 lno = tvb_get_letohs(tvb, offset);
13039                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13040                 offset += 2;
13041
13042                 break;
13043         case 0x02:      /*TRANS2_FIND_NEXT2*/
13044                 /* search count */
13045                 si->info_count = tvb_get_letohs(tvb, offset);
13046                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13047                 offset += 2;
13048
13049                 /* end of search */
13050                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13051                 offset += 2;
13052
13053                 /* ea_error_offset, only a 16 bit integer here*/
13054                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13055                 offset += 2;
13056
13057                 /* last name offset */
13058                 lno = tvb_get_letohs(tvb, offset);
13059                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13060                 offset += 2;
13061
13062                 break;
13063         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
13064                 /* no parameter block here */
13065                 break;
13066         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
13067                 /* ea_error_offset, only a 16 bit integer here*/
13068                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13069                 offset += 2;
13070
13071                 break;
13072         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
13073                 /* ea_error_offset, only a 16 bit integer here*/
13074                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13075                 offset += 2;
13076
13077                 break;
13078         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
13079                 /* ea_error_offset, only a 16 bit integer here*/
13080                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13081                 offset += 2;
13082
13083                 break;
13084         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
13085                 /* ea_error_offset, only a 16 bit integer here*/
13086                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13087                 offset += 2;
13088
13089                 break;
13090         case 0x09:      /*TRANS2_FSCTL*/
13091                 /* XXX dont know how to dissect this one (yet)*/
13092
13093                 /*
13094                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13095                  * Extensions Version 3.0, Document Version 1.11,
13096                  * July 19, 1990" says this this contains a
13097                  * "File system specific return parameter block".
13098                  * (That means we may not be able to dissect it in any
13099                  * case.)
13100                  */
13101                 break;
13102         case 0x0a:      /*TRANS2_IOCTL2*/
13103                 /* XXX dont know how to dissect this one (yet)*/
13104
13105                 /*
13106                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13107                  * Extensions Version 3.0, Document Version 1.11,
13108                  * July 19, 1990" says this this contains a
13109                  * "Device/function specific return parameter block".
13110                  * (That means we may not be able to dissect it in any
13111                  * case.)
13112                  */
13113                 break;
13114         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
13115                 /* Find Notify information level */
13116                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13117
13118                 /* Monitor handle */
13119                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
13120                 offset += 2;
13121
13122                 /* Change count */
13123                 si->info_count = tvb_get_letohs(tvb, offset);
13124                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13125                 offset += 2;
13126
13127                 /* ea_error_offset, only a 16 bit integer here*/
13128                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13129                 offset += 2;
13130
13131                 break;
13132         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
13133                 /* Find Notify information level */
13134                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13135
13136                 /* Change count */
13137                 si->info_count = tvb_get_letohs(tvb, offset);
13138                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13139                 offset += 2;
13140
13141                 /* ea_error_offset, only a 16 bit integer here*/
13142                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13143                 offset += 2;
13144
13145                 break;
13146         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
13147                 /* ea error offset, only a 16 bit integer here */
13148                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13149                 offset += 2;
13150
13151                 break;
13152         case 0x0e:      /*TRANS2_SESSION_SETUP*/
13153                 /* XXX dont know how to dissect this one (yet)*/
13154                 break;
13155         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
13156                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
13157                 break;
13158         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13159                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
13160                 break;
13161         case -1:
13162                 /*
13163                  * We don't know what the matching request was; don't
13164                  * bother putting anything else into the tree for the data.
13165                  */
13166                 offset += pc;
13167                 break;
13168         }
13169
13170         /* ooops there were data we didnt know how to process */
13171         if(offset<pc){
13172                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
13173                 offset += pc-offset;
13174         }
13175 }
13176
13177
13178 static int
13179 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13180 {
13181         guint8 sc, wc;
13182         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
13183         smb_info_t *si;
13184         smb_transact2_info_t *t2i = NULL;
13185         guint16 bc;
13186         int padcnt;
13187         gboolean dissected_trans;
13188         fragment_data *r_fd = NULL;
13189         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
13190         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
13191         gboolean save_fragmented;
13192
13193         si = (smb_info_t *)pinfo->private_data;
13194
13195         switch(si->cmd){
13196         case SMB_COM_TRANSACTION2:
13197                 /* transaction2 */
13198                 if (si->sip != NULL) {
13199                         t2i = si->sip->extra_info;
13200                 } else
13201                         t2i = NULL;
13202                 if (t2i == NULL) {
13203                         /*
13204                          * We didn't see the matching request, so we don't
13205                          * know what type of transaction this is.
13206                          */
13207                         proto_tree_add_text(tree, tvb, 0, 0,
13208                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
13209                         if (check_col(pinfo->cinfo, COL_INFO)) {
13210                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
13211                         }
13212                 } else {
13213                         si->info_level = t2i->info_level;
13214                         if (t2i->subcmd == -1) {
13215                                 /*
13216                                  * We didn't manage to extract the subcommand
13217                                  * from the matching request (perhaps because
13218                                  * the frame was short), so we don't know what
13219                                  * type of transaction this is.
13220                                  */
13221                                 proto_tree_add_text(tree, tvb, 0, 0,
13222                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
13223                                 if (check_col(pinfo->cinfo, COL_INFO)) {
13224                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
13225                                 }
13226                         } else {
13227                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
13228                                 if (check_col(pinfo->cinfo, COL_INFO)) {
13229                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13230                                                 val_to_str(t2i->subcmd,
13231                                                         trans2_cmd_vals,
13232                                                         "<unknown (0x%02x)>"));
13233                                 }
13234                         }
13235                 }
13236                 break;
13237         }
13238
13239         WORD_COUNT;
13240
13241         /* total param count, only a 16bit integer here */
13242         tp = tvb_get_letohs(tvb, offset);
13243         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
13244         offset += 2;
13245
13246         /* total data count, only a 16 bit integer here */
13247         td = tvb_get_letohs(tvb, offset);
13248         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
13249         offset += 2;
13250
13251         /* 2 reserved bytes */
13252         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
13253         offset += 2;
13254
13255         /* param count */
13256         pc = tvb_get_letohs(tvb, offset);
13257         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
13258         offset += 2;
13259
13260         /* param offset */
13261         po = tvb_get_letohs(tvb, offset);
13262         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
13263         offset += 2;
13264
13265         /* param disp */
13266         pd = tvb_get_letohs(tvb, offset);
13267         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
13268         offset += 2;
13269
13270         /* data count */
13271         dc = tvb_get_letohs(tvb, offset);
13272         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
13273         offset += 2;
13274
13275         /* data offset */
13276         od = tvb_get_letohs(tvb, offset);
13277         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
13278         offset += 2;
13279
13280         /* data disp */
13281         dd = tvb_get_letohs(tvb, offset);
13282         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
13283         offset += 2;
13284
13285         /* setup count */
13286         sc = tvb_get_guint8(tvb, offset);
13287         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
13288         offset += 1;
13289
13290         /* reserved byte */
13291         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
13292         offset += 1;
13293
13294
13295         /* if there were any setup bytes, put them in a tvb for later */
13296         if(sc){
13297                 if((2*sc)>tvb_length_remaining(tvb, offset)){
13298                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
13299                 } else {
13300                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
13301                 }
13302                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
13303         } else {
13304                 s_tvb = NULL;
13305                 sp_tvb=NULL;
13306         }
13307         offset += 2*sc;
13308
13309
13310         BYTE_COUNT;
13311
13312
13313         /* reassembly of SMB Transaction data payload.
13314            In this section we do reassembly of both the data and parameters
13315            blocks of the SMB transaction command.
13316         */
13317         save_fragmented = pinfo->fragmented;
13318         /* do we need reassembly? */
13319         if( (td!=dc) || (tp!=pc) ){
13320                 /* oh yeah, either data or parameter section needs
13321                    reassembly
13322                 */
13323                 pinfo->fragmented = TRUE;
13324                 if(smb_trans_reassembly){
13325                         /* ...and we were told to do reassembly */
13326                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
13327                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
13328                                                              po, pc, pd, td+tp);
13329
13330                         }
13331                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
13332                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
13333                                                              od, dc, dd+tp, td+tp);
13334                         }
13335                 }
13336         }
13337
13338         /* if we got a reassembled fd structure from the reassembly routine we must
13339            create pd_tvb from it
13340         */
13341         if(r_fd){
13342                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
13343                                              r_fd->datalen);
13344                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
13345                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
13346                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
13347         }
13348
13349
13350         if(pd_tvb){
13351                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
13352                 if(tp){
13353                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
13354                 }
13355                 if(td){
13356                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
13357                 }
13358         } else {
13359                 /* It was not reassembled. Do as best as we can.
13360                  * in this case we always try to dissect the stuff if
13361                  * data and param displacement is 0. i.e. for the first
13362                  * (and maybe only) packet.
13363                  */
13364                 if( (pd==0) && (dd==0) ){
13365                         int min;
13366                         int reported_min;
13367                         min = MIN(pc,tvb_length_remaining(tvb,po));
13368                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
13369                         if(min && reported_min) {
13370                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
13371                         }
13372                         min = MIN(dc,tvb_length_remaining(tvb,od));
13373                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
13374                         if(min && reported_min) {
13375                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
13376                         }
13377                         /*
13378                          * A tvbuff containing the parameters
13379                          * and the data.
13380                          * XXX - check pc and dc as well?
13381                          */
13382                         if (tvb_length_remaining(tvb, po)){
13383                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
13384                         }
13385                 }
13386         }
13387
13388
13389
13390         /* parameters */
13391         if(po>offset){
13392                 /* We have some padding bytes.
13393                 */
13394                 padcnt = po-offset;
13395                 if (padcnt > bc)
13396                         padcnt = bc;
13397                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
13398                 COUNT_BYTES(padcnt);
13399         }
13400         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
13401                 /* TRANSACTION2 parameters*/
13402                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
13403         }
13404         COUNT_BYTES(pc);
13405
13406
13407         /* data */
13408         if(od>offset){
13409                 /* We have some initial padding bytes.
13410                 */
13411                 padcnt = od-offset;
13412                 if (padcnt > bc)
13413                         padcnt = bc;
13414                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
13415                 COUNT_BYTES(padcnt);
13416         }
13417         /*
13418          * If the data count is bigger than the count of bytes
13419          * remaining, clamp it so that the count of bytes remaining
13420          * doesn't go negative.
13421          */
13422         if (dc > bc)
13423                 dc = bc;
13424         COUNT_BYTES(dc);
13425
13426
13427
13428         /* from now on, everything is in separate tvbuffs so we dont count
13429            the bytes with COUNT_BYTES any more.
13430            neither do we reference offset any more (which by now points to the
13431            first byte AFTER this PDU */
13432
13433
13434         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
13435                 /* TRANSACTION2 parameters*/
13436                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
13437         }
13438
13439
13440         if(si->cmd==SMB_COM_TRANSACTION){
13441                 smb_transact_info_t *tri;
13442
13443                 dissected_trans = FALSE;
13444                 if (si->sip != NULL)
13445                         tri = si->sip->extra_info;
13446                 else
13447                         tri = NULL;
13448                 if (tri != NULL) {
13449                         switch(tri->subcmd){
13450
13451                         case TRANSACTION_PIPE:
13452                                 /* This function is safe to call for
13453                                    s_tvb==sp_tvb==NULL, i.e. if we don't
13454                                    know them at this point.
13455                                    It's also safe to call if "p_tvb"
13456                                    or "d_tvb" are null.
13457                                 */
13458                                 if( pd_tvb) {
13459                                         dissected_trans = dissect_pipe_smb(
13460                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
13461                                                 d_tvb, NULL, pinfo, top_tree);
13462                                 }
13463                                 break;
13464
13465                         case TRANSACTION_MAILSLOT:
13466                                 /* This one should be safe to call
13467                                    even if s_tvb and sp_tvb is NULL
13468                                 */
13469                                 if(d_tvb){
13470                                         dissected_trans = dissect_mailslot_smb(
13471                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
13472                                                 top_tree);
13473                                 }
13474                                 break;
13475                         }
13476                 }
13477                 if (!dissected_trans) {
13478                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
13479                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
13480                 }
13481         }
13482
13483
13484         if( (p_tvb==0) && (d_tvb==0) ){
13485                 if(check_col(pinfo->cinfo, COL_INFO)){
13486                         col_append_str(pinfo->cinfo, COL_INFO,
13487                                        "[transact continuation]");
13488                 }
13489         }
13490
13491         pinfo->fragmented = save_fragmented;
13492         END_OF_SMB
13493
13494         return offset;
13495 }
13496
13497
13498 static int
13499 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13500 {
13501         guint8 wc;
13502         guint16 bc;
13503
13504         WORD_COUNT;
13505
13506         /* Monitor handle */
13507         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
13508         offset += 2;
13509
13510         BYTE_COUNT;
13511
13512         END_OF_SMB
13513
13514         return offset;
13515 }
13516
13517 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
13518    END Transaction/Transaction2 Primary and secondary requests
13519    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
13520
13521
13522 static int
13523 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13524 {
13525         guint8 wc;
13526         guint16 bc;
13527
13528         WORD_COUNT;
13529
13530         if (wc != 0) {
13531                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
13532                 offset += wc*2;
13533         }
13534
13535         BYTE_COUNT;
13536
13537         if (bc != 0) {
13538                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
13539                 offset += bc;
13540                 bc = 0;
13541         }
13542
13543         END_OF_SMB
13544
13545         return offset;
13546 }
13547
13548 typedef struct _smb_function {
13549        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13550        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13551 } smb_function;
13552
13553 static smb_function smb_dissector[256] = {
13554   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
13555   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
13556   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
13557   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
13558   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
13559   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
13560   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
13561   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
13562   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
13563   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
13564   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
13565   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
13566   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
13567   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
13568   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
13569   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
13570
13571   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
13572   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
13573   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
13574   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
13575   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
13576   /* 0x15 */  {dissect_unknown, dissect_unknown},
13577   /* 0x16 */  {dissect_unknown, dissect_unknown},
13578   /* 0x17 */  {dissect_unknown, dissect_unknown},
13579   /* 0x18 */  {dissect_unknown, dissect_unknown},
13580   /* 0x19 */  {dissect_unknown, dissect_unknown},
13581   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
13582   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
13583   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
13584   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
13585   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
13586   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
13587
13588   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
13589   /* 0x21 */  {dissect_unknown, dissect_unknown},
13590   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
13591   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
13592   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
13593   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
13594   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
13595   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
13596   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
13597   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
13598   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
13599   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
13600   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
13601   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
13602   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
13603   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
13604
13605   /* 0x30 */  {dissect_unknown, dissect_unknown},
13606   /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
13607   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
13608   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
13609   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
13610   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
13611   /* 0x36 */  {dissect_unknown, dissect_unknown},
13612   /* 0x37 */  {dissect_unknown, dissect_unknown},
13613   /* 0x38 */  {dissect_unknown, dissect_unknown},
13614   /* 0x39 */  {dissect_unknown, dissect_unknown},
13615   /* 0x3a */  {dissect_unknown, dissect_unknown},
13616   /* 0x3b */  {dissect_unknown, dissect_unknown},
13617   /* 0x3c */  {dissect_unknown, dissect_unknown},
13618   /* 0x3d */  {dissect_unknown, dissect_unknown},
13619   /* 0x3e */  {dissect_unknown, dissect_unknown},
13620   /* 0x3f */  {dissect_unknown, dissect_unknown},
13621
13622   /* 0x40 */  {dissect_unknown, dissect_unknown},
13623   /* 0x41 */  {dissect_unknown, dissect_unknown},
13624   /* 0x42 */  {dissect_unknown, dissect_unknown},
13625   /* 0x43 */  {dissect_unknown, dissect_unknown},
13626   /* 0x44 */  {dissect_unknown, dissect_unknown},
13627   /* 0x45 */  {dissect_unknown, dissect_unknown},
13628   /* 0x46 */  {dissect_unknown, dissect_unknown},
13629   /* 0x47 */  {dissect_unknown, dissect_unknown},
13630   /* 0x48 */  {dissect_unknown, dissect_unknown},
13631   /* 0x49 */  {dissect_unknown, dissect_unknown},
13632   /* 0x4a */  {dissect_unknown, dissect_unknown},
13633   /* 0x4b */  {dissect_unknown, dissect_unknown},
13634   /* 0x4c */  {dissect_unknown, dissect_unknown},
13635   /* 0x4d */  {dissect_unknown, dissect_unknown},
13636   /* 0x4e */  {dissect_unknown, dissect_unknown},
13637   /* 0x4f */  {dissect_unknown, dissect_unknown},
13638
13639   /* 0x50 */  {dissect_unknown, dissect_unknown},
13640   /* 0x51 */  {dissect_unknown, dissect_unknown},
13641   /* 0x52 */  {dissect_unknown, dissect_unknown},
13642   /* 0x53 */  {dissect_unknown, dissect_unknown},
13643   /* 0x54 */  {dissect_unknown, dissect_unknown},
13644   /* 0x55 */  {dissect_unknown, dissect_unknown},
13645   /* 0x56 */  {dissect_unknown, dissect_unknown},
13646   /* 0x57 */  {dissect_unknown, dissect_unknown},
13647   /* 0x58 */  {dissect_unknown, dissect_unknown},
13648   /* 0x59 */  {dissect_unknown, dissect_unknown},
13649   /* 0x5a */  {dissect_unknown, dissect_unknown},
13650   /* 0x5b */  {dissect_unknown, dissect_unknown},
13651   /* 0x5c */  {dissect_unknown, dissect_unknown},
13652   /* 0x5d */  {dissect_unknown, dissect_unknown},
13653   /* 0x5e */  {dissect_unknown, dissect_unknown},
13654   /* 0x5f */  {dissect_unknown, dissect_unknown},
13655
13656   /* 0x60 */  {dissect_unknown, dissect_unknown},
13657   /* 0x61 */  {dissect_unknown, dissect_unknown},
13658   /* 0x62 */  {dissect_unknown, dissect_unknown},
13659   /* 0x63 */  {dissect_unknown, dissect_unknown},
13660   /* 0x64 */  {dissect_unknown, dissect_unknown},
13661   /* 0x65 */  {dissect_unknown, dissect_unknown},
13662   /* 0x66 */  {dissect_unknown, dissect_unknown},
13663   /* 0x67 */  {dissect_unknown, dissect_unknown},
13664   /* 0x68 */  {dissect_unknown, dissect_unknown},
13665   /* 0x69 */  {dissect_unknown, dissect_unknown},
13666   /* 0x6a */  {dissect_unknown, dissect_unknown},
13667   /* 0x6b */  {dissect_unknown, dissect_unknown},
13668   /* 0x6c */  {dissect_unknown, dissect_unknown},
13669   /* 0x6d */  {dissect_unknown, dissect_unknown},
13670   /* 0x6e */  {dissect_unknown, dissect_unknown},
13671   /* 0x6f */  {dissect_unknown, dissect_unknown},
13672
13673   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
13674   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
13675   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
13676   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
13677   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
13678   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
13679   /* 0x76 */  {dissect_unknown, dissect_unknown},
13680   /* 0x77 */  {dissect_unknown, dissect_unknown},
13681   /* 0x78 */  {dissect_unknown, dissect_unknown},
13682   /* 0x79 */  {dissect_unknown, dissect_unknown},
13683   /* 0x7a */  {dissect_unknown, dissect_unknown},
13684   /* 0x7b */  {dissect_unknown, dissect_unknown},
13685   /* 0x7c */  {dissect_unknown, dissect_unknown},
13686   /* 0x7d */  {dissect_unknown, dissect_unknown},
13687   /* 0x7e */  {dissect_unknown, dissect_unknown},
13688   /* 0x7f */  {dissect_unknown, dissect_unknown},
13689
13690   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
13691   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
13692   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
13693   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
13694   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
13695   /* 0x85 */  {dissect_unknown, dissect_unknown},
13696   /* 0x86 */  {dissect_unknown, dissect_unknown},
13697   /* 0x87 */  {dissect_unknown, dissect_unknown},
13698   /* 0x88 */  {dissect_unknown, dissect_unknown},
13699   /* 0x89 */  {dissect_unknown, dissect_unknown},
13700   /* 0x8a */  {dissect_unknown, dissect_unknown},
13701   /* 0x8b */  {dissect_unknown, dissect_unknown},
13702   /* 0x8c */  {dissect_unknown, dissect_unknown},
13703   /* 0x8d */  {dissect_unknown, dissect_unknown},
13704   /* 0x8e */  {dissect_unknown, dissect_unknown},
13705   /* 0x8f */  {dissect_unknown, dissect_unknown},
13706
13707   /* 0x90 */  {dissect_unknown, dissect_unknown},
13708   /* 0x91 */  {dissect_unknown, dissect_unknown},
13709   /* 0x92 */  {dissect_unknown, dissect_unknown},
13710   /* 0x93 */  {dissect_unknown, dissect_unknown},
13711   /* 0x94 */  {dissect_unknown, dissect_unknown},
13712   /* 0x95 */  {dissect_unknown, dissect_unknown},
13713   /* 0x96 */  {dissect_unknown, dissect_unknown},
13714   /* 0x97 */  {dissect_unknown, dissect_unknown},
13715   /* 0x98 */  {dissect_unknown, dissect_unknown},
13716   /* 0x99 */  {dissect_unknown, dissect_unknown},
13717   /* 0x9a */  {dissect_unknown, dissect_unknown},
13718   /* 0x9b */  {dissect_unknown, dissect_unknown},
13719   /* 0x9c */  {dissect_unknown, dissect_unknown},
13720   /* 0x9d */  {dissect_unknown, dissect_unknown},
13721   /* 0x9e */  {dissect_unknown, dissect_unknown},
13722   /* 0x9f */  {dissect_unknown, dissect_unknown},
13723
13724   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
13725   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
13726   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
13727   /* 0xa3 */  {dissect_unknown, dissect_unknown},
13728   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
13729   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
13730   /* 0xa6 */  {dissect_unknown, dissect_unknown},
13731   /* 0xa7 */  {dissect_unknown, dissect_unknown},
13732   /* 0xa8 */  {dissect_unknown, dissect_unknown},
13733   /* 0xa9 */  {dissect_unknown, dissect_unknown},
13734   /* 0xaa */  {dissect_unknown, dissect_unknown},
13735   /* 0xab */  {dissect_unknown, dissect_unknown},
13736   /* 0xac */  {dissect_unknown, dissect_unknown},
13737   /* 0xad */  {dissect_unknown, dissect_unknown},
13738   /* 0xae */  {dissect_unknown, dissect_unknown},
13739   /* 0xaf */  {dissect_unknown, dissect_unknown},
13740
13741   /* 0xb0 */  {dissect_unknown, dissect_unknown},
13742   /* 0xb1 */  {dissect_unknown, dissect_unknown},
13743   /* 0xb2 */  {dissect_unknown, dissect_unknown},
13744   /* 0xb3 */  {dissect_unknown, dissect_unknown},
13745   /* 0xb4 */  {dissect_unknown, dissect_unknown},
13746   /* 0xb5 */  {dissect_unknown, dissect_unknown},
13747   /* 0xb6 */  {dissect_unknown, dissect_unknown},
13748   /* 0xb7 */  {dissect_unknown, dissect_unknown},
13749   /* 0xb8 */  {dissect_unknown, dissect_unknown},
13750   /* 0xb9 */  {dissect_unknown, dissect_unknown},
13751   /* 0xba */  {dissect_unknown, dissect_unknown},
13752   /* 0xbb */  {dissect_unknown, dissect_unknown},
13753   /* 0xbc */  {dissect_unknown, dissect_unknown},
13754   /* 0xbd */  {dissect_unknown, dissect_unknown},
13755   /* 0xbe */  {dissect_unknown, dissect_unknown},
13756   /* 0xbf */  {dissect_unknown, dissect_unknown},
13757
13758   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
13759   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
13760   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
13761   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
13762   /* 0xc4 */  {dissect_unknown, dissect_unknown},
13763   /* 0xc5 */  {dissect_unknown, dissect_unknown},
13764   /* 0xc6 */  {dissect_unknown, dissect_unknown},
13765   /* 0xc7 */  {dissect_unknown, dissect_unknown},
13766   /* 0xc8 */  {dissect_unknown, dissect_unknown},
13767   /* 0xc9 */  {dissect_unknown, dissect_unknown},
13768   /* 0xca */  {dissect_unknown, dissect_unknown},
13769   /* 0xcb */  {dissect_unknown, dissect_unknown},
13770   /* 0xcc */  {dissect_unknown, dissect_unknown},
13771   /* 0xcd */  {dissect_unknown, dissect_unknown},
13772   /* 0xce */  {dissect_unknown, dissect_unknown},
13773   /* 0xcf */  {dissect_unknown, dissect_unknown},
13774
13775   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
13776   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
13777   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
13778   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
13779   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
13780   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
13781   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
13782   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
13783   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
13784   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
13785   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
13786   /* 0xdb */  {dissect_unknown, dissect_unknown},
13787   /* 0xdc */  {dissect_unknown, dissect_unknown},
13788   /* 0xdd */  {dissect_unknown, dissect_unknown},
13789   /* 0xde */  {dissect_unknown, dissect_unknown},
13790   /* 0xdf */  {dissect_unknown, dissect_unknown},
13791
13792   /* 0xe0 */  {dissect_unknown, dissect_unknown},
13793   /* 0xe1 */  {dissect_unknown, dissect_unknown},
13794   /* 0xe2 */  {dissect_unknown, dissect_unknown},
13795   /* 0xe3 */  {dissect_unknown, dissect_unknown},
13796   /* 0xe4 */  {dissect_unknown, dissect_unknown},
13797   /* 0xe5 */  {dissect_unknown, dissect_unknown},
13798   /* 0xe6 */  {dissect_unknown, dissect_unknown},
13799   /* 0xe7 */  {dissect_unknown, dissect_unknown},
13800   /* 0xe8 */  {dissect_unknown, dissect_unknown},
13801   /* 0xe9 */  {dissect_unknown, dissect_unknown},
13802   /* 0xea */  {dissect_unknown, dissect_unknown},
13803   /* 0xeb */  {dissect_unknown, dissect_unknown},
13804   /* 0xec */  {dissect_unknown, dissect_unknown},
13805   /* 0xed */  {dissect_unknown, dissect_unknown},
13806   /* 0xee */  {dissect_unknown, dissect_unknown},
13807   /* 0xef */  {dissect_unknown, dissect_unknown},
13808
13809   /* 0xf0 */  {dissect_unknown, dissect_unknown},
13810   /* 0xf1 */  {dissect_unknown, dissect_unknown},
13811   /* 0xf2 */  {dissect_unknown, dissect_unknown},
13812   /* 0xf3 */  {dissect_unknown, dissect_unknown},
13813   /* 0xf4 */  {dissect_unknown, dissect_unknown},
13814   /* 0xf5 */  {dissect_unknown, dissect_unknown},
13815   /* 0xf6 */  {dissect_unknown, dissect_unknown},
13816   /* 0xf7 */  {dissect_unknown, dissect_unknown},
13817   /* 0xf8 */  {dissect_unknown, dissect_unknown},
13818   /* 0xf9 */  {dissect_unknown, dissect_unknown},
13819   /* 0xfa */  {dissect_unknown, dissect_unknown},
13820   /* 0xfb */  {dissect_unknown, dissect_unknown},
13821   /* 0xfc */  {dissect_unknown, dissect_unknown},
13822   /* 0xfd */  {dissect_unknown, dissect_unknown},
13823   /* 0xfe */  {dissect_unknown, dissect_unknown},
13824   /* 0xff */  {dissect_unknown, dissect_unknown},
13825 };
13826
13827 static int
13828 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
13829 {
13830         int old_offset = offset;
13831         smb_info_t *si;
13832
13833         si = pinfo->private_data;
13834         if(cmd!=0xff){
13835                 proto_item *cmd_item;
13836                 proto_tree *cmd_tree;
13837                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13838
13839                 if (check_col(pinfo->cinfo, COL_INFO)) {
13840                         if(first_pdu){
13841                                 col_append_fstr(pinfo->cinfo, COL_INFO,
13842                                         "%s %s",
13843                                         decode_smb_name(cmd),
13844                                         (si->request)? "Request" : "Response");
13845                         } else {
13846                                 col_append_fstr(pinfo->cinfo, COL_INFO,
13847                                         "; %s",
13848                                         decode_smb_name(cmd));
13849                         }
13850
13851                 }
13852
13853                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
13854                         "%s %s (0x%02x)",
13855                         decode_smb_name(cmd),
13856                         (si->request)?"Request":"Response",
13857                         cmd);
13858
13859                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
13860
13861                 dissector = (si->request)?
13862                         smb_dissector[cmd].request:smb_dissector[cmd].response;
13863
13864                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
13865                 proto_item_set_len(cmd_item, offset-old_offset);
13866         }
13867         return offset;
13868 }
13869
13870
13871 /* NOTE: this value_string array will also be used to access data directly by
13872  * index instead of val_to_str() since
13873  * 1, the array will always span every value from 0x00 to 0xff and
13874  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
13875  * This means that this value_string array MUST always
13876  * 1, contain all entries 0x00 to 0xff
13877  * 2, all entries must be in order.
13878  */
13879 const value_string smb_cmd_vals[] = {
13880   { 0x00, "Create Directory" },
13881   { 0x01, "Delete Directory" },
13882   { 0x02, "Open" },
13883   { 0x03, "Create" },
13884   { 0x04, "Close" },
13885   { 0x05, "Flush" },
13886   { 0x06, "Delete" },
13887   { 0x07, "Rename" },
13888   { 0x08, "Query Information" },
13889   { 0x09, "Set Information" },
13890   { 0x0A, "Read" },
13891   { 0x0B, "Write" },
13892   { 0x0C, "Lock Byte Range" },
13893   { 0x0D, "Unlock Byte Range" },
13894   { 0x0E, "Create Temp" },
13895   { 0x0F, "Create New" },
13896   { 0x10, "Check Directory" },
13897   { 0x11, "Process Exit" },
13898   { 0x12, "Seek" },
13899   { 0x13, "Lock And Read" },
13900   { 0x14, "Write And Unlock" },
13901   { 0x15, "unknown-0x15" },
13902   { 0x16, "unknown-0x16" },
13903   { 0x17, "unknown-0x17" },
13904   { 0x18, "unknown-0x18" },
13905   { 0x19, "unknown-0x19" },
13906   { 0x1A, "Read Raw" },
13907   { 0x1B, "Read MPX" },
13908   { 0x1C, "Read MPX Secondary" },
13909   { 0x1D, "Write Raw" },
13910   { 0x1E, "Write MPX" },
13911   { 0x1F, "Write MPX Secondary" },
13912   { 0x20, "Write Complete" },
13913   { 0x21, "unknown-0x21" },
13914   { 0x22, "Set Information2" },
13915   { 0x23, "Query Information2" },
13916   { 0x24, "Locking AndX" },
13917   { 0x25, "Transaction" },
13918   { 0x26, "Transaction Secondary" },
13919   { 0x27, "IOCTL" },
13920   { 0x28, "IOCTL Secondary" },
13921   { 0x29, "Copy" },
13922   { 0x2A, "Move" },
13923   { 0x2B, "Echo" },
13924   { 0x2C, "Write And Close" },
13925   { 0x2D, "Open AndX" },
13926   { 0x2E, "Read AndX" },
13927   { 0x2F, "Write AndX" },
13928   { 0x30, "unknown-0x30" },
13929   { 0x31, "Close And Tree Disconnect" },
13930   { 0x32, "Transaction2" },
13931   { 0x33, "Transaction2 Secondary" },
13932   { 0x34, "Find Close2" },
13933   { 0x35, "Find Notify Close" },
13934   { 0x36, "unknown-0x36" },
13935   { 0x37, "unknown-0x37" },
13936   { 0x38, "unknown-0x38" },
13937   { 0x39, "unknown-0x39" },
13938   { 0x3A, "unknown-0x3A" },
13939   { 0x3B, "unknown-0x3B" },
13940   { 0x3C, "unknown-0x3C" },
13941   { 0x3D, "unknown-0x3D" },
13942   { 0x3E, "unknown-0x3E" },
13943   { 0x3F, "unknown-0x3F" },
13944   { 0x40, "unknown-0x40" },
13945   { 0x41, "unknown-0x41" },
13946   { 0x42, "unknown-0x42" },
13947   { 0x43, "unknown-0x43" },
13948   { 0x44, "unknown-0x44" },
13949   { 0x45, "unknown-0x45" },
13950   { 0x46, "unknown-0x46" },
13951   { 0x47, "unknown-0x47" },
13952   { 0x48, "unknown-0x48" },
13953   { 0x49, "unknown-0x49" },
13954   { 0x4A, "unknown-0x4A" },
13955   { 0x4B, "unknown-0x4B" },
13956   { 0x4C, "unknown-0x4C" },
13957   { 0x4D, "unknown-0x4D" },
13958   { 0x4E, "unknown-0x4E" },
13959   { 0x4F, "unknown-0x4F" },
13960   { 0x50, "unknown-0x50" },
13961   { 0x51, "unknown-0x51" },
13962   { 0x52, "unknown-0x52" },
13963   { 0x53, "unknown-0x53" },
13964   { 0x54, "unknown-0x54" },
13965   { 0x55, "unknown-0x55" },
13966   { 0x56, "unknown-0x56" },
13967   { 0x57, "unknown-0x57" },
13968   { 0x58, "unknown-0x58" },
13969   { 0x59, "unknown-0x59" },
13970   { 0x5A, "unknown-0x5A" },
13971   { 0x5B, "unknown-0x5B" },
13972   { 0x5C, "unknown-0x5C" },
13973   { 0x5D, "unknown-0x5D" },
13974   { 0x5E, "unknown-0x5E" },
13975   { 0x5F, "unknown-0x5F" },
13976   { 0x60, "unknown-0x60" },
13977   { 0x61, "unknown-0x61" },
13978   { 0x62, "unknown-0x62" },
13979   { 0x63, "unknown-0x63" },
13980   { 0x64, "unknown-0x64" },
13981   { 0x65, "unknown-0x65" },
13982   { 0x66, "unknown-0x66" },
13983   { 0x67, "unknown-0x67" },
13984   { 0x68, "unknown-0x68" },
13985   { 0x69, "unknown-0x69" },
13986   { 0x6A, "unknown-0x6A" },
13987   { 0x6B, "unknown-0x6B" },
13988   { 0x6C, "unknown-0x6C" },
13989   { 0x6D, "unknown-0x6D" },
13990   { 0x6E, "unknown-0x6E" },
13991   { 0x6F, "unknown-0x6F" },
13992   { 0x70, "Tree Connect" },
13993   { 0x71, "Tree Disconnect" },
13994   { 0x72, "Negotiate Protocol" },
13995   { 0x73, "Session Setup AndX" },
13996   { 0x74, "Logoff AndX" },
13997   { 0x75, "Tree Connect AndX" },
13998   { 0x76, "unknown-0x76" },
13999   { 0x77, "unknown-0x77" },
14000   { 0x78, "unknown-0x78" },
14001   { 0x79, "unknown-0x79" },
14002   { 0x7A, "unknown-0x7A" },
14003   { 0x7B, "unknown-0x7B" },
14004   { 0x7C, "unknown-0x7C" },
14005   { 0x7D, "unknown-0x7D" },
14006   { 0x7E, "unknown-0x7E" },
14007   { 0x7F, "unknown-0x7F" },
14008   { 0x80, "Query Information Disk" },
14009   { 0x81, "Search" },
14010   { 0x82, "Find" },
14011   { 0x83, "Find Unique" },
14012   { 0x84, "Find Close" },
14013   { 0x85, "unknown-0x85" },
14014   { 0x86, "unknown-0x86" },
14015   { 0x87, "unknown-0x87" },
14016   { 0x88, "unknown-0x88" },
14017   { 0x89, "unknown-0x89" },
14018   { 0x8A, "unknown-0x8A" },
14019   { 0x8B, "unknown-0x8B" },
14020   { 0x8C, "unknown-0x8C" },
14021   { 0x8D, "unknown-0x8D" },
14022   { 0x8E, "unknown-0x8E" },
14023   { 0x8F, "unknown-0x8F" },
14024   { 0x90, "unknown-0x90" },
14025   { 0x91, "unknown-0x91" },
14026   { 0x92, "unknown-0x92" },
14027   { 0x93, "unknown-0x93" },
14028   { 0x94, "unknown-0x94" },
14029   { 0x95, "unknown-0x95" },
14030   { 0x96, "unknown-0x96" },
14031   { 0x97, "unknown-0x97" },
14032   { 0x98, "unknown-0x98" },
14033   { 0x99, "unknown-0x99" },
14034   { 0x9A, "unknown-0x9A" },
14035   { 0x9B, "unknown-0x9B" },
14036   { 0x9C, "unknown-0x9C" },
14037   { 0x9D, "unknown-0x9D" },
14038   { 0x9E, "unknown-0x9E" },
14039   { 0x9F, "unknown-0x9F" },
14040   { 0xA0, "NT Transact" },
14041   { 0xA1, "NT Transact Secondary" },
14042   { 0xA2, "NT Create AndX" },
14043   { 0xA3, "unknown-0xA3" },
14044   { 0xA4, "NT Cancel" },
14045   { 0xA5, "NT Rename" },
14046   { 0xA6, "unknown-0xA6" },
14047   { 0xA7, "unknown-0xA7" },
14048   { 0xA8, "unknown-0xA8" },
14049   { 0xA9, "unknown-0xA9" },
14050   { 0xAA, "unknown-0xAA" },
14051   { 0xAB, "unknown-0xAB" },
14052   { 0xAC, "unknown-0xAC" },
14053   { 0xAD, "unknown-0xAD" },
14054   { 0xAE, "unknown-0xAE" },
14055   { 0xAF, "unknown-0xAF" },
14056   { 0xB0, "unknown-0xB0" },
14057   { 0xB1, "unknown-0xB1" },
14058   { 0xB2, "unknown-0xB2" },
14059   { 0xB3, "unknown-0xB3" },
14060   { 0xB4, "unknown-0xB4" },
14061   { 0xB5, "unknown-0xB5" },
14062   { 0xB6, "unknown-0xB6" },
14063   { 0xB7, "unknown-0xB7" },
14064   { 0xB8, "unknown-0xB8" },
14065   { 0xB9, "unknown-0xB9" },
14066   { 0xBA, "unknown-0xBA" },
14067   { 0xBB, "unknown-0xBB" },
14068   { 0xBC, "unknown-0xBC" },
14069   { 0xBD, "unknown-0xBD" },
14070   { 0xBE, "unknown-0xBE" },
14071   { 0xBF, "unknown-0xBF" },
14072   { 0xC0, "Open Print File" },
14073   { 0xC1, "Write Print File" },
14074   { 0xC2, "Close Print File" },
14075   { 0xC3, "Get Print Queue" },
14076   { 0xC4, "unknown-0xC4" },
14077   { 0xC5, "unknown-0xC5" },
14078   { 0xC6, "unknown-0xC6" },
14079   { 0xC7, "unknown-0xC7" },
14080   { 0xC8, "unknown-0xC8" },
14081   { 0xC9, "unknown-0xC9" },
14082   { 0xCA, "unknown-0xCA" },
14083   { 0xCB, "unknown-0xCB" },
14084   { 0xCC, "unknown-0xCC" },
14085   { 0xCD, "unknown-0xCD" },
14086   { 0xCE, "unknown-0xCE" },
14087   { 0xCF, "unknown-0xCF" },
14088   { 0xD0, "Send Single Block Message" },
14089   { 0xD1, "Send Broadcast Message" },
14090   { 0xD2, "Forward User Name" },
14091   { 0xD3, "Cancel Forward" },
14092   { 0xD4, "Get Machine Name" },
14093   { 0xD5, "Send Start of Multi-block Message" },
14094   { 0xD6, "Send End of Multi-block Message" },
14095   { 0xD7, "Send Text of Multi-block Message" },
14096   { 0xD8, "SMBreadbulk" },
14097   { 0xD9, "SMBwritebulk" },
14098   { 0xDA, "SMBwritebulkdata" },
14099   { 0xDB, "unknown-0xDB" },
14100   { 0xDC, "unknown-0xDC" },
14101   { 0xDD, "unknown-0xDD" },
14102   { 0xDE, "unknown-0xDE" },
14103   { 0xDF, "unknown-0xDF" },
14104   { 0xE0, "unknown-0xE0" },
14105   { 0xE1, "unknown-0xE1" },
14106   { 0xE2, "unknown-0xE2" },
14107   { 0xE3, "unknown-0xE3" },
14108   { 0xE4, "unknown-0xE4" },
14109   { 0xE5, "unknown-0xE5" },
14110   { 0xE6, "unknown-0xE6" },
14111   { 0xE7, "unknown-0xE7" },
14112   { 0xE8, "unknown-0xE8" },
14113   { 0xE9, "unknown-0xE9" },
14114   { 0xEA, "unknown-0xEA" },
14115   { 0xEB, "unknown-0xEB" },
14116   { 0xEC, "unknown-0xEC" },
14117   { 0xED, "unknown-0xED" },
14118   { 0xEE, "unknown-0xEE" },
14119   { 0xEF, "unknown-0xEF" },
14120   { 0xF0, "unknown-0xF0" },
14121   { 0xF1, "unknown-0xF1" },
14122   { 0xF2, "unknown-0xF2" },
14123   { 0xF3, "unknown-0xF3" },
14124   { 0xF4, "unknown-0xF4" },
14125   { 0xF5, "unknown-0xF5" },
14126   { 0xF6, "unknown-0xF6" },
14127   { 0xF7, "unknown-0xF7" },
14128   { 0xF8, "unknown-0xF8" },
14129   { 0xF9, "unknown-0xF9" },
14130   { 0xFA, "unknown-0xFA" },
14131   { 0xFB, "unknown-0xFB" },
14132   { 0xFC, "unknown-0xFC" },
14133   { 0xFD, "unknown-0xFD" },
14134   { 0xFE, "SMBinvalid" },
14135   { 0xFF, "unknown-0xFF" },
14136   { 0x00, NULL },
14137 };
14138
14139 static char *decode_smb_name(unsigned char cmd)
14140 {
14141   return(smb_cmd_vals[cmd].strptr);
14142 }
14143
14144
14145
14146 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14147  * Everything TVBUFFIFIED above this line
14148  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
14149
14150
14151 static void
14152 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
14153 {
14154         conv_tables_t *ct = ctarg;
14155
14156         if (ct->unmatched)
14157                 g_hash_table_destroy(ct->unmatched);
14158         if (ct->matched)
14159                 g_hash_table_destroy(ct->matched);
14160         if (ct->dcerpc_fid_to_frame)
14161                 g_hash_table_destroy(ct->dcerpc_fid_to_frame);
14162         if (ct->dcerpc_frame_to_dcerpc_pdu)
14163                 g_hash_table_destroy(ct->dcerpc_frame_to_dcerpc_pdu);
14164         if (ct->tid_service)
14165                 g_hash_table_destroy(ct->tid_service);
14166 }
14167
14168 static void
14169 smb_init_protocol(void)
14170 {
14171         if (smb_saved_info_key_chunk)
14172                 g_mem_chunk_destroy(smb_saved_info_key_chunk);
14173         if (smb_saved_info_chunk)
14174                 g_mem_chunk_destroy(smb_saved_info_chunk);
14175         if (smb_nt_transact_info_chunk)
14176                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
14177         if (smb_transact2_info_chunk)
14178                 g_mem_chunk_destroy(smb_transact2_info_chunk);
14179         if (smb_transact_info_chunk)
14180                 g_mem_chunk_destroy(smb_transact_info_chunk);
14181
14182         /*
14183          * Free the hash tables attached to the conversation table
14184          * structures, and then free the list of conversation table
14185          * data structures (which doesn't free the data structures
14186          * themselves; that's done by destroying the chunk from
14187          * which they were allocated).
14188          */
14189         if (conv_tables) {
14190                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
14191                 g_slist_free(conv_tables);
14192                 conv_tables = NULL;
14193         }
14194
14195         /*
14196          * Now destroy the chunk from which the conversation table
14197          * structures were allocated.
14198          */
14199         if (conv_tables_chunk)
14200                 g_mem_chunk_destroy(conv_tables_chunk);
14201
14202         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
14203             sizeof(smb_saved_info_t),
14204             smb_saved_info_init_count * sizeof(smb_saved_info_t),
14205             G_ALLOC_ONLY);
14206         smb_saved_info_key_chunk = g_mem_chunk_new("smb_saved_info_key_chunk",
14207             sizeof(smb_saved_info_key_t),
14208             smb_saved_info_init_count * sizeof(smb_saved_info_key_t),
14209             G_ALLOC_ONLY);
14210         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
14211             sizeof(smb_nt_transact_info_t),
14212             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
14213             G_ALLOC_ONLY);
14214         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
14215             sizeof(smb_transact2_info_t),
14216             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
14217             G_ALLOC_ONLY);
14218         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
14219             sizeof(smb_transact_info_t),
14220             smb_transact_info_init_count * sizeof(smb_transact_info_t),
14221             G_ALLOC_ONLY);
14222         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
14223             sizeof(conv_tables_t),
14224             conv_tables_count * sizeof(conv_tables_t),
14225             G_ALLOC_ONLY);
14226 }
14227
14228 static const value_string errcls_types[] = {
14229   { SMB_SUCCESS, "Success"},
14230   { SMB_ERRDOS, "DOS Error"},
14231   { SMB_ERRSRV, "Server Error"},
14232   { SMB_ERRHRD, "Hardware Error"},
14233   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
14234   { 0, NULL }
14235 };
14236
14237 const value_string DOS_errors[] = {
14238   {0, "Success"},
14239   {SMBE_insufficientbuffer, "Insufficient buffer"},
14240   {SMBE_badfunc, "Invalid function (or system call)"},
14241   {SMBE_badfile, "File not found (pathname error)"},
14242   {SMBE_badpath, "Directory not found"},
14243   {SMBE_nofids, "Too many open files"},
14244   {SMBE_noaccess, "Access denied"},
14245   {SMBE_badfid, "Invalid fid"},
14246   {SMBE_nomem,  "Out of memory"},
14247   {SMBE_badmem, "Invalid memory block address"},
14248   {SMBE_badenv, "Invalid environment"},
14249   {SMBE_badaccess, "Invalid open mode"},
14250   {SMBE_baddata, "Invalid data (only from ioctl call)"},
14251   {SMBE_res, "Reserved error code?"},
14252   {SMBE_baddrive, "Invalid drive"},
14253   {SMBE_remcd, "Attempt to delete current directory"},
14254   {SMBE_diffdevice, "Rename/move across different filesystems"},
14255   {SMBE_nofiles, "No more files found in file search"},
14256   {SMBE_badshare, "Share mode on file conflict with open mode"},
14257   {SMBE_lock, "Lock request conflicts with existing lock"},
14258   {SMBE_unsup, "Request unsupported, returned by Win 95"},
14259   {SMBE_nosuchshare, "Requested share does not exist"},
14260   {SMBE_filexists, "File in operation already exists"},
14261   {SMBE_cannotopen, "Cannot open the file specified"},
14262   {SMBE_unknownlevel, "Unknown info level"},
14263   {SMBE_invalidname, "Invalid name"},
14264   {SMBE_badpipe, "Named pipe invalid"},
14265   {SMBE_pipebusy, "All instances of pipe are busy"},
14266   {SMBE_pipeclosing, "Named pipe close in progress"},
14267   {SMBE_notconnected, "No process on other end of named pipe"},
14268   {SMBE_moredata, "More data to be returned"},
14269   {SMBE_baddirectory,  "Invalid directory name in a path."},
14270   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
14271   {SMBE_eas_nsup, "Extended attributes not supported"},
14272   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
14273   {SMBE_unknownipc, "Unknown IPC Operation"},
14274   {SMBE_noipc, "Don't support ipc"},
14275   {SMBE_alreadyexists, "File already exists"},
14276   {SMBE_unknownprinterdriver, "Unknown printer driver"},
14277   {SMBE_invalidprintername, "Invalid printer name"},
14278   {SMBE_printeralreadyexists, "Printer already exists"},
14279   {SMBE_invaliddatatype, "Invalid data type"},
14280   {SMBE_invalidenvironment, "Invalid environment"},
14281   {SMBE_printerdriverinuse, "Printer driver in use"},
14282   {SMBE_invalidparam, "Invalid parameter"},
14283   {SMBE_invalidformsize, "Invalid form size"},
14284   {SMBE_invalidsecuritydescriptor, "Invalid security descriptor"},
14285   {SMBE_invalidowner, "Invalid owner"},
14286   {SMBE_nomoreitems, "No more items"},
14287   {SMBE_serverunavailable, "Server unavailable"},
14288   {0, NULL}
14289   };
14290
14291 /* Error codes for the ERRSRV class */
14292
14293 static const value_string SRV_errors[] = {
14294   {SMBE_error, "Non specific error code"},
14295   {SMBE_badpw, "Bad password"},
14296   {SMBE_badtype, "Reserved"},
14297   {SMBE_access, "No permissions to perform the requested operation"},
14298   {SMBE_invnid, "TID invalid"},
14299   {SMBE_invnetname, "Invalid network name. Service not found"},
14300   {SMBE_invdevice, "Invalid device"},
14301   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
14302   {SMBE_qfull, "Print queue full"},
14303   {SMBE_qtoobig, "Queued item too big"},
14304   {SMBE_qeof, "EOF on print queue dump"},
14305   {SMBE_invpfid, "Invalid print file in smb_fid"},
14306   {SMBE_smbcmd, "Unrecognised command"},
14307   {SMBE_srverror, "SMB server internal error"},
14308   {SMBE_filespecs, "Fid and pathname invalid combination"},
14309   {SMBE_badlink, "Bad link in request ???"},
14310   {SMBE_badpermits, "Access specified for a file is not valid"},
14311   {SMBE_badpid, "Bad process id in request"},
14312   {SMBE_setattrmode, "Attribute mode invalid"},
14313   {SMBE_paused, "Message server paused"},
14314   {SMBE_msgoff, "Not receiving messages"},
14315   {SMBE_noroom, "No room for message"},
14316   {SMBE_rmuns, "Too many remote usernames"},
14317   {SMBE_timeout, "Operation timed out"},
14318   {SMBE_noresource, "No resources currently available for request."},
14319   {SMBE_toomanyuids, "Too many userids"},
14320   {SMBE_baduid, "Bad userid"},
14321   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
14322   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
14323   {SMBE_contMPX, "Resume MPX mode"},
14324   {SMBE_badPW, "Bad Password???"},
14325   {SMBE_nosupport, "Operation not supported"},
14326   { 0, NULL}
14327 };
14328
14329 /* Error codes for the ERRHRD class */
14330
14331 static const value_string HRD_errors[] = {
14332   {SMBE_nowrite, "Read only media"},
14333   {SMBE_badunit, "Unknown device"},
14334   {SMBE_notready, "Drive not ready"},
14335   {SMBE_badcmd, "Unknown command"},
14336   {SMBE_data, "Data (CRC) error"},
14337   {SMBE_badreq, "Bad request structure length"},
14338   {SMBE_seek, "Seek error"},
14339   {SMBE_badmedia, "Unknown media type"},
14340   {SMBE_badsector, "Sector not found"},
14341   {SMBE_nopaper, "Printer out of paper"},
14342   {SMBE_write, "Write fault"},
14343   {SMBE_read, "Read fault"},
14344   {SMBE_general, "General failure"},
14345   {SMBE_badshare, "A open conflicts with an existing open"},
14346   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
14347   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
14348   {SMBE_FCBunavail, "No FCBs are available to process request"},
14349   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
14350   {SMBE_diskfull, "Disk full???"},
14351   {0, NULL}
14352 };
14353
14354 static char *decode_smb_error(guint8 errcls, guint16 errcode)
14355 {
14356
14357   switch (errcls) {
14358
14359   case SMB_SUCCESS:
14360
14361     return("No Error");   /* No error ??? */
14362     break;
14363
14364   case SMB_ERRDOS:
14365
14366     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
14367     break;
14368
14369   case SMB_ERRSRV:
14370
14371     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
14372     break;
14373
14374   case SMB_ERRHRD:
14375
14376     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
14377     break;
14378
14379   default:
14380
14381     return("Unknown error class!");
14382
14383   }
14384
14385 }
14386
14387
14388 /* These are the MS country codes from
14389
14390         http://www.unicode.org/unicode/onlinedat/countries.html
14391
14392    For countries that share the same number, I choose to use only the
14393    name of the largest country. Apologies for this. If this offends you,
14394    here is the table to change that.
14395
14396    This also includes the code of 0 for "Default", which isn't in
14397    that list, but is in Microsoft's SDKs and the Cygnus "winnls.h"
14398    header file.  Presumably it means "don't override the setting
14399    on the user's machine".
14400
14401    Future versions of Microsoft's "winnls.h" header file might include
14402    additional codes; the current version matches the Unicode Consortium's
14403    table.
14404 */
14405 const value_string ms_country_codes[] = {
14406         {  0,   "Default"},
14407         {  1,   "USA"},
14408         {  2,   "Canada"},
14409         {  7,   "Russia"},
14410         { 20,   "Egypt"},
14411         { 27,   "South Africa"},
14412         { 30,   "Greece"},
14413         { 31,   "Netherlands"},
14414         { 32,   "Belgium"},
14415         { 33,   "France"},
14416         { 34,   "Spain"},
14417         { 36,   "Hungary"},
14418         { 39,   "Italy"},
14419         { 40,   "Romania"},
14420         { 41,   "Switzerland"},
14421         { 43,   "Austria"},
14422         { 44,   "United Kingdom"},
14423         { 45,   "Denmark"},
14424         { 46,   "Sweden"},
14425         { 47,   "Norway"},
14426         { 48,   "Poland"},
14427         { 49,   "Germany"},
14428         { 51,   "Peru"},
14429         { 52,   "Mexico"},
14430         { 54,   "Argentina"},
14431         { 55,   "Brazil"},
14432         { 56,   "Chile"},
14433         { 57,   "Colombia"},
14434         { 58,   "Venezuela"},
14435         { 60,   "Malaysia"},
14436         { 61,   "Australia"},
14437         { 62,   "Indonesia"},
14438         { 63,   "Philippines"},
14439         { 64,   "New Zealand"},
14440         { 65,   "Singapore"},
14441         { 66,   "Thailand"},
14442         { 81,   "Japan"},
14443         { 82,   "South Korea"},
14444         { 84,   "Viet Nam"},
14445         { 86,   "China"},
14446         { 90,   "Turkey"},
14447         { 91,   "India"},
14448         { 92,   "Pakistan"},
14449         {212,   "Morocco"},
14450         {213,   "Algeria"},
14451         {216,   "Tunisia"},
14452         {218,   "Libya"},
14453         {254,   "Kenya"},
14454         {263,   "Zimbabwe"},
14455         {298,   "Faroe Islands"},
14456         {351,   "Portugal"},
14457         {352,   "Luxembourg"},
14458         {353,   "Ireland"},
14459         {354,   "Iceland"},
14460         {355,   "Albania"},
14461         {358,   "Finland"},
14462         {359,   "Bulgaria"},
14463         {370,   "Lithuania"},
14464         {371,   "Latvia"},
14465         {372,   "Estonia"},
14466         {374,   "Armenia"},
14467         {375,   "Belarus"},
14468         {380,   "Ukraine"},
14469         {381,   "Serbia"},
14470         {385,   "Croatia"},
14471         {386,   "Slovenia"},
14472         {389,   "Macedonia"},
14473         {420,   "Czech Republic"},
14474         {421,   "Slovak Republic"},
14475         {501,   "Belize"},
14476         {502,   "Guatemala"},
14477         {503,   "El Salvador"},
14478         {504,   "Honduras"},
14479         {505,   "Nicaragua"},
14480         {506,   "Costa Rica"},
14481         {507,   "Panama"},
14482         {591,   "Bolivia"},
14483         {593,   "Ecuador"},
14484         {595,   "Paraguay"},
14485         {598,   "Uruguay"},
14486         {673,   "Brunei Darussalam"},
14487         {852,   "Hong Kong"},
14488         {853,   "Macau"},
14489         {886,   "Taiwan"},
14490         {960,   "Maldives"},
14491         {961,   "Lebanon"},
14492         {962,   "Jordan"},
14493         {963,   "Syria"},
14494         {964,   "Iraq"},
14495         {965,   "Kuwait"},
14496         {966,   "Saudi Arabia"},
14497         {967,   "Yemen"},
14498         {968,   "Oman"},
14499         {971,   "United Arab Emirates"},
14500         {972,   "Israel"},
14501         {973,   "Bahrain"},
14502         {974,   "Qatar"},
14503         {976,   "Mongolia"},
14504         {981,   "Iran"},
14505         {994,   "Azerbaijan"},
14506         {995,   "Georgia"},
14507         {996,   "Kyrgyzstan"},
14508
14509         {0,     NULL}
14510 };
14511
14512 /*
14513  * NT error codes.
14514  *
14515  * From
14516  *
14517  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
14518  */
14519 const value_string NT_errors[] = {
14520   { 0x00000000, "STATUS_SUCCESS" },
14521   { 0x00000000, "STATUS_WAIT_0" },
14522   { 0x00000001, "STATUS_WAIT_1" },
14523   { 0x00000002, "STATUS_WAIT_2" },
14524   { 0x00000003, "STATUS_WAIT_3" },
14525   { 0x0000003F, "STATUS_WAIT_63" },
14526   { 0x00000080, "STATUS_ABANDONED" },
14527   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
14528   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
14529   { 0x000000C0, "STATUS_USER_APC" },
14530   { 0x00000100, "STATUS_KERNEL_APC" },
14531   { 0x00000101, "STATUS_ALERTED" },
14532   { 0x00000102, "STATUS_TIMEOUT" },
14533   { 0x00000103, "STATUS_PENDING" },
14534   { 0x00000104, "STATUS_REPARSE" },
14535   { 0x00000105, "STATUS_MORE_ENTRIES" },
14536   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
14537   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
14538   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
14539   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
14540   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
14541   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
14542   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
14543   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
14544   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
14545   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
14546   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
14547   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
14548   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
14549   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
14550   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
14551   { 0x00000116, "STATUS_CRASH_DUMP" },
14552   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
14553   { 0x00000118, "STATUS_REPARSE_OBJECT" },
14554   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
14555   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
14556   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
14557   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
14558   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
14559   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
14560   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
14561   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
14562   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
14563   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
14564   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
14565   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
14566   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
14567   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
14568   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
14569   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
14570   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
14571   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
14572   { 0x40000012, "STATUS_EVENT_DONE" },
14573   { 0x40000013, "STATUS_EVENT_PENDING" },
14574   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
14575   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
14576   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
14577   { 0x40000017, "STATUS_WAS_UNLOCKED" },
14578   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
14579   { 0x40000019, "STATUS_WAS_LOCKED" },
14580   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
14581   { 0x4000001B, "STATUS_ALREADY_WIN32" },
14582   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
14583   { 0x4000001D, "STATUS_WX86_CONTINUE" },
14584   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
14585   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
14586   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
14587   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
14588   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
14589   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
14590   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
14591   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
14592   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
14593   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
14594   { 0x80000003, "STATUS_BREAKPOINT" },
14595   { 0x80000004, "STATUS_SINGLE_STEP" },
14596   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
14597   { 0x80000006, "STATUS_NO_MORE_FILES" },
14598   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
14599   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
14600   { 0x8000000B, "STATUS_NO_INHERITANCE" },
14601   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
14602   { 0x8000000D, "STATUS_PARTIAL_COPY" },
14603   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
14604   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
14605   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
14606   { 0x80000011, "STATUS_DEVICE_BUSY" },
14607   { 0x80000012, "STATUS_NO_MORE_EAS" },
14608   { 0x80000013, "STATUS_INVALID_EA_NAME" },
14609   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
14610   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
14611   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
14612   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
14613   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
14614   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
14615   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
14616   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
14617   { 0x8000001D, "STATUS_BUS_RESET" },
14618   { 0x8000001E, "STATUS_END_OF_MEDIA" },
14619   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
14620   { 0x80000020, "STATUS_MEDIA_CHECK" },
14621   { 0x80000021, "STATUS_SETMARK_DETECTED" },
14622   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
14623   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
14624   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
14625   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
14626   { 0x80000026, "STATUS_LONGJUMP" },
14627   { 0x80040111, "MAPI_E_LOGON_FAILED" },
14628   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
14629   { 0x80090301, "SEC_E_INVALID_HANDLE" },
14630   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
14631   { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
14632   { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
14633   { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
14634   { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
14635   { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
14636   { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
14637   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
14638   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
14639   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
14640   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
14641   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
14642   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
14643   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
14644   { 0xC0000008, "STATUS_INVALID_HANDLE" },
14645   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
14646   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
14647   { 0xC000000B, "STATUS_INVALID_CID" },
14648   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
14649   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
14650   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
14651   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
14652   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
14653   { 0xC0000011, "STATUS_END_OF_FILE" },
14654   { 0xC0000012, "STATUS_WRONG_VOLUME" },
14655   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
14656   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
14657   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
14658   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
14659   { 0xC0000017, "STATUS_NO_MEMORY" },
14660   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
14661   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
14662   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
14663   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
14664   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
14665   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
14666   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
14667   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
14668   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
14669   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
14670   { 0xC0000022, "STATUS_ACCESS_DENIED" },
14671   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
14672   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
14673   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
14674   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
14675   { 0xC0000027, "STATUS_UNWIND" },
14676   { 0xC0000028, "STATUS_BAD_STACK" },
14677   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
14678   { 0xC000002A, "STATUS_NOT_LOCKED" },
14679   { 0xC000002B, "STATUS_PARITY_ERROR" },
14680   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
14681   { 0xC000002D, "STATUS_NOT_COMMITTED" },
14682   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
14683   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
14684   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
14685   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
14686   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
14687   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
14688   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
14689   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
14690   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
14691   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
14692   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
14693   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
14694   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
14695   { 0xC000003C, "STATUS_DATA_OVERRUN" },
14696   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
14697   { 0xC000003E, "STATUS_DATA_ERROR" },
14698   { 0xC000003F, "STATUS_CRC_ERROR" },
14699   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
14700   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
14701   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
14702   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
14703   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
14704   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
14705   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
14706   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
14707   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
14708   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
14709   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
14710   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
14711   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
14712   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
14713   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
14714   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
14715   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
14716   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
14717   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
14718   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
14719   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
14720   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
14721   { 0xC0000056, "STATUS_DELETE_PENDING" },
14722   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
14723   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
14724   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
14725   { 0xC000005A, "STATUS_INVALID_OWNER" },
14726   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
14727   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
14728   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
14729   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
14730   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
14731   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
14732   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
14733   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
14734   { 0xC0000063, "STATUS_USER_EXISTS" },
14735   { 0xC0000064, "STATUS_NO_SUCH_USER" },
14736   { 0xC0000065, "STATUS_GROUP_EXISTS" },
14737   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
14738   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
14739   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
14740   { 0xC0000069, "STATUS_LAST_ADMIN" },
14741   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
14742   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
14743   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
14744   { 0xC000006D, "STATUS_LOGON_FAILURE" },
14745   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
14746   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
14747   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
14748   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
14749   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
14750   { 0xC0000073, "STATUS_NONE_MAPPED" },
14751   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
14752   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
14753   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
14754   { 0xC0000077, "STATUS_INVALID_ACL" },
14755   { 0xC0000078, "STATUS_INVALID_SID" },
14756   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
14757   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
14758   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
14759   { 0xC000007C, "STATUS_NO_TOKEN" },
14760   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
14761   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
14762   { 0xC000007F, "STATUS_DISK_FULL" },
14763   { 0xC0000080, "STATUS_SERVER_DISABLED" },
14764   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
14765   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
14766   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
14767   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
14768   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
14769   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
14770   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
14771   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
14772   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
14773   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
14774   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
14775   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
14776   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
14777   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
14778   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
14779   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
14780   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
14781   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
14782   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
14783   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
14784   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
14785   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
14786   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
14787   { 0xC0000098, "STATUS_FILE_INVALID" },
14788   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
14789   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
14790   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
14791   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
14792   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
14793   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
14794   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
14795   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
14796   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
14797   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
14798   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
14799   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
14800   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
14801   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
14802   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
14803   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
14804   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
14805   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
14806   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
14807   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
14808   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
14809   { 0xC00000AE, "STATUS_PIPE_BUSY" },
14810   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
14811   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
14812   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
14813   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
14814   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
14815   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
14816   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
14817   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
14818   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
14819   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
14820   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
14821   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
14822   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
14823   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
14824   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
14825   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
14826   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
14827   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
14828   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
14829   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
14830   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
14831   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
14832   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
14833   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
14834   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
14835   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
14836   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
14837   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
14838   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
14839   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
14840   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
14841   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
14842   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
14843   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
14844   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
14845   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
14846   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
14847   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
14848   { 0xC00000D5, "STATUS_FILE_RENAMED" },
14849   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
14850   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
14851   { 0xC00000D8, "STATUS_CANT_WAIT" },
14852   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
14853   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
14854   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
14855   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
14856   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
14857   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
14858   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
14859   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
14860   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
14861   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
14862   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
14863   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
14864   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
14865   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
14866   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
14867   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
14868   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
14869   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
14870   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
14871   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
14872   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
14873   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
14874   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
14875   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
14876   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
14877   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
14878   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
14879   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
14880   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
14881   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
14882   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
14883   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
14884   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
14885   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
14886   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
14887   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
14888   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
14889   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
14890   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
14891   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
14892   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
14893   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
14894   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
14895   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
14896   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
14897   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
14898   { 0xC0000107, "STATUS_FILES_OPEN" },
14899   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
14900   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
14901   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
14902   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
14903   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
14904   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
14905   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
14906   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
14907   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
14908   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
14909   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
14910   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
14911   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
14912   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
14913   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
14914   { 0xC0000117, "STATUS_NO_LDT" },
14915   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
14916   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
14917   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
14918   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
14919   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
14920   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
14921   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
14922   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
14923   { 0xC0000120, "STATUS_CANCELLED" },
14924   { 0xC0000121, "STATUS_CANNOT_DELETE" },
14925   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
14926   { 0xC0000123, "STATUS_FILE_DELETED" },
14927   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
14928   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
14929   { 0xC0000126, "STATUS_SPECIAL_USER" },
14930   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
14931   { 0xC0000128, "STATUS_FILE_CLOSED" },
14932   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
14933   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
14934   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
14935   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
14936   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
14937   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
14938   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
14939   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
14940   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
14941   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
14942   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
14943   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
14944   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
14945   { 0xC0000136, "STATUS_OPEN_FAILED" },
14946   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
14947   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
14948   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
14949   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
14950   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
14951   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
14952   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
14953   { 0xC000013E, "STATUS_LINK_FAILED" },
14954   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
14955   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
14956   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
14957   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
14958   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
14959   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
14960   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
14961   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
14962   { 0xC0000147, "STATUS_NO_PAGEFILE" },
14963   { 0xC0000148, "STATUS_INVALID_LEVEL" },
14964   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
14965   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
14966   { 0xC000014B, "STATUS_PIPE_BROKEN" },
14967   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
14968   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
14969   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
14970   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
14971   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
14972   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
14973   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
14974   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
14975   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
14976   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
14977   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
14978   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
14979   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
14980   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
14981   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
14982   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
14983   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
14984   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
14985   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
14986   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
14987   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
14988   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
14989   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
14990   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
14991   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
14992   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
14993   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
14994   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
14995   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
14996   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
14997   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
14998   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
14999   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
15000   { 0xC000016D, "STATUS_FT_ORPHANING" },
15001   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
15002   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
15003   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
15004   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
15005   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
15006   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
15007   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
15008   { 0xC0000178, "STATUS_NO_MEDIA" },
15009   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
15010   { 0xC000017B, "STATUS_INVALID_MEMBER" },
15011   { 0xC000017C, "STATUS_KEY_DELETED" },
15012   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
15013   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
15014   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
15015   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
15016   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
15017   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
15018   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
15019   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
15020   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
15021   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
15022   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
15023   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
15024   { 0xC0000189, "STATUS_TOO_LATE" },
15025   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
15026   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
15027   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
15028   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
15029   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
15030   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
15031   { 0xC0000190, "STATUS_TRUST_FAILURE" },
15032   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
15033   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
15034   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
15035   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
15036   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
15037   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
15038   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
15039   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
15040   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
15041   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
15042   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
15043   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
15044   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
15045   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
15046   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
15047   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
15048   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
15049   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
15050   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
15051   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
15052   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
15053   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
15054   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
15055   { 0xC000020D, "STATUS_CONNECTION_RESET" },
15056   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
15057   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
15058   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
15059   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
15060   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
15061   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
15062   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
15063   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
15064   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
15065   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
15066   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
15067   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
15068   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
15069   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
15070   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
15071   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
15072   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
15073   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
15074   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
15075   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
15076   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
15077   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
15078   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
15079   { 0xC0000225, "STATUS_NOT_FOUND" },
15080   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
15081   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
15082   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
15083   { 0xC0000229, "STATUS_FAIL_CHECK" },
15084   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
15085   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
15086   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
15087   { 0xC000022D, "STATUS_RETRY" },
15088   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
15089   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
15090   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
15091   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
15092   { 0xC0000232, "STATUS_INVALID_VARIANT" },
15093   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
15094   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
15095   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
15096   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
15097   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
15098   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
15099   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
15100   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
15101   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
15102   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
15103   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
15104   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
15105   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
15106   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
15107   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
15108   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
15109   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
15110   { 0xC0000244, "STATUS_AUDIT_FAILED" },
15111   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
15112   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
15113   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
15114   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
15115   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
15116   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
15117   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
15118   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
15119   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
15120   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
15121   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
15122   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
15123   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
15124   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
15125   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
15126   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
15127   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
15128   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
15129   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
15130   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
15131   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
15132   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
15133   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
15134   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
15135   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
15136   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
15137   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
15138   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
15139   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
15140   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
15141   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
15142   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
15143   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
15144   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
15145   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
15146   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
15147   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
15148   { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
15149   { 0xC0000272, "STATUS_NO_MATCH" },
15150   { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
15151   { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
15152   { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
15153   { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
15154   { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
15155   { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
15156   { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
15157   { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
15158   { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
15159   { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
15160   { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
15161   { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
15162   { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
15163   { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
15164   { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
15165   { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
15166   { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
15167   { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
15168   { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
15169   { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
15170   { 0xC000028E, "STATUS_NO_EFS" },
15171   { 0xC000028F, "STATUS_WRONG_EFS" },
15172   { 0xC0000290, "STATUS_NO_USER_KEYS" },
15173   { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
15174   { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
15175   { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
15176   { 0x40000294, "STATUS_WAKE_SYSTEM" },
15177   { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
15178   { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
15179   { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
15180   { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
15181   { 0xC0000299, "STATUS_SHARED_POLICY" },
15182   { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
15183   { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
15184   { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
15185   { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
15186   { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
15187   { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
15188   { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
15189   { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
15190   { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
15191   { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
15192   { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
15193   { 0xC00002A5, "STATUS_DS_BUSY" },
15194   { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
15195   { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
15196   { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
15197   { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
15198   { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
15199   { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
15200   { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
15201   { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
15202   { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
15203   { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
15204   { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
15205   { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
15206   { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
15207   { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
15208   { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
15209   { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
15210   { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
15211   { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
15212   { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
15213   { 0xC00002B9, "STATUS_NOINTERFACE" },
15214   { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
15215   { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
15216   { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
15217   { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
15218   { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
15219   { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
15220   { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
15221   { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
15222   { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
15223   { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
15224   { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
15225   { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
15226   { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
15227   { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
15228   { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
15229   { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
15230   { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
15231   { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
15232   { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
15233   { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
15234   { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
15235   { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
15236   { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
15237   { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
15238   { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
15239   { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
15240   { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
15241   { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
15242   { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
15243   { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
15244   { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
15245   { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
15246   { 0xC00002E1, "STATUS_DS_CANT_START" },
15247   { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
15248   { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
15249   { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
15250   { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
15251   { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
15252   { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
15253   { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
15254   { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
15255   { 0xC0009898, "STATUS_WOW_ASSERTION" },
15256   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
15257   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
15258   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
15259   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
15260   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
15261   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
15262   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
15263   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
15264   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
15265   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
15266   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
15267   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
15268   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
15269   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
15270   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
15271   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
15272   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
15273   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
15274   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
15275   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
15276   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
15277   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
15278   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
15279   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
15280   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
15281   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
15282   { 0xC002001B, "RPC_NT_CALL_FAILED" },
15283   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
15284   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
15285   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
15286   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
15287   { 0xC0020022, "RPC_NT_INVALID_TAG" },
15288   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
15289   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
15290   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
15291   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
15292   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
15293   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
15294   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
15295   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
15296   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
15297   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
15298   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
15299   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
15300   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
15301   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
15302   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
15303   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
15304   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
15305   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
15306   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
15307   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
15308   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
15309   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
15310   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
15311   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
15312   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
15313   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
15314   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
15315   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
15316   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
15317   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
15318   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
15319   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
15320   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
15321   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
15322   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
15323   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
15324   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
15325   { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
15326   { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
15327   { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
15328   { 0xC002100A, "RPC_P_SEND_FAILED" },
15329   { 0xC002100B, "RPC_P_TIMEOUT" },
15330   { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
15331   { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
15332   { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
15333   { 0xC0021015, "RPC_P_THREAD_LISTENING" },
15334   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
15335   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
15336   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
15337   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
15338   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
15339   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
15340   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
15341   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
15342   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
15343   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
15344   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
15345   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
15346   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
15347   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
15348   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
15349   { 0xC002004C, "EPT_NT_CANT_CREATE" },
15350   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
15351   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
15352   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
15353   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
15354   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
15355   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
15356   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
15357   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
15358   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
15359   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
15360   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
15361   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
15362   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
15363   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
15364   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
15365   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
15366   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
15367   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
15368   { 0,          NULL }
15369 };
15370
15371
15372
15373 static const true_false_string tfs_smb_flags_lock = {
15374         "Lock&Read, Write&Unlock are supported",
15375         "Lock&Read, Write&Unlock are not supported"
15376 };
15377 static const true_false_string tfs_smb_flags_receive_buffer = {
15378         "Receive buffer has been posted",
15379         "Receive buffer has not been posted"
15380 };
15381 static const true_false_string tfs_smb_flags_caseless = {
15382         "Path names are caseless",
15383         "Path names are case sensitive"
15384 };
15385 static const true_false_string tfs_smb_flags_canon = {
15386         "Pathnames are canonicalized",
15387         "Pathnames are not canonicalized"
15388 };
15389 static const true_false_string tfs_smb_flags_oplock = {
15390         "OpLock requested/granted",
15391         "OpLock not requested/granted"
15392 };
15393 static const true_false_string tfs_smb_flags_notify = {
15394         "Notify client on all modifications",
15395         "Notify client only on open"
15396 };
15397 static const true_false_string tfs_smb_flags_response = {
15398         "Message is a response to the client/redirector",
15399         "Message is a request to the server"
15400 };
15401
15402 static int
15403 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15404 {
15405         guint8 mask;
15406         proto_item *item = NULL;
15407         proto_tree *tree = NULL;
15408
15409         mask = tvb_get_guint8(tvb, offset);
15410
15411         if(parent_tree){
15412                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
15413                         "Flags: 0x%02x", mask);
15414                 tree = proto_item_add_subtree(item, ett_smb_flags);
15415         }
15416         proto_tree_add_boolean(tree, hf_smb_flags_response,
15417                 tvb, offset, 1, mask);
15418         proto_tree_add_boolean(tree, hf_smb_flags_notify,
15419                 tvb, offset, 1, mask);
15420         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
15421                 tvb, offset, 1, mask);
15422         proto_tree_add_boolean(tree, hf_smb_flags_canon,
15423                 tvb, offset, 1, mask);
15424         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
15425                 tvb, offset, 1, mask);
15426         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
15427                 tvb, offset, 1, mask);
15428         proto_tree_add_boolean(tree, hf_smb_flags_lock,
15429                 tvb, offset, 1, mask);
15430         offset += 1;
15431         return offset;
15432 }
15433
15434
15435
15436 static const true_false_string tfs_smb_flags2_long_names_allowed = {
15437         "Long file names are allowed in the response",
15438         "Long file names are not allowed in the response"
15439 };
15440 static const true_false_string tfs_smb_flags2_ea = {
15441         "Extended attributes are supported",
15442         "Extended attributes are not supported"
15443 };
15444 static const true_false_string tfs_smb_flags2_sec_sig = {
15445         "Security signatures are supported",
15446         "Security signatures are not supported"
15447 };
15448 static const true_false_string tfs_smb_flags2_long_names_used = {
15449         "Path names in request are long file names",
15450         "Path names in request are not long file names"
15451 };
15452 static const true_false_string tfs_smb_flags2_esn = {
15453         "Extended security negotiation is supported",
15454         "Extended security negotiation is not supported"
15455 };
15456 static const true_false_string tfs_smb_flags2_dfs = {
15457         "Resolve pathnames with Dfs",
15458         "Don't resolve pathnames with Dfs"
15459 };
15460 static const true_false_string tfs_smb_flags2_roe = {
15461         "Permit reads if execute-only",
15462         "Don't permit reads if execute-only"
15463 };
15464 static const true_false_string tfs_smb_flags2_nt_error = {
15465         "Error codes are NT error codes",
15466         "Error codes are DOS error codes"
15467 };
15468 static const true_false_string tfs_smb_flags2_string = {
15469         "Strings are Unicode",
15470         "Strings are ASCII"
15471 };
15472 static int
15473 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15474 {
15475         guint16 mask;
15476         proto_item *item = NULL;
15477         proto_tree *tree = NULL;
15478
15479         mask = tvb_get_letohs(tvb, offset);
15480
15481         if(parent_tree){
15482                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
15483                         "Flags2: 0x%04x", mask);
15484                 tree = proto_item_add_subtree(item, ett_smb_flags2);
15485         }
15486
15487         proto_tree_add_boolean(tree, hf_smb_flags2_string,
15488                 tvb, offset, 2, mask);
15489         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
15490                 tvb, offset, 2, mask);
15491         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
15492                 tvb, offset, 2, mask);
15493         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
15494                 tvb, offset, 2, mask);
15495         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
15496                 tvb, offset, 2, mask);
15497         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
15498                 tvb, offset, 2, mask);
15499         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
15500                 tvb, offset, 2, mask);
15501         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
15502                 tvb, offset, 2, mask);
15503         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
15504                 tvb, offset, 2, mask);
15505
15506         offset += 2;
15507         return offset;
15508 }
15509
15510
15511
15512 #define SMB_FLAGS_DIRN 0x80
15513
15514
15515 static void
15516 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
15517 {
15518         int offset = 0;
15519         proto_item *item = NULL, *hitem = NULL;
15520         proto_tree *tree = NULL, *htree = NULL;
15521         guint8          flags;
15522         guint16         flags2;
15523         static smb_info_t       si_arr[20];
15524         static int si_counter=0;
15525         smb_info_t              *si;
15526         smb_saved_info_t *sip = NULL;
15527         smb_saved_info_key_t key;
15528         smb_saved_info_key_t *new_key;
15529         guint32 nt_status = 0;
15530         guint8 errclass = 0;
15531         guint16 errcode = 0;
15532         guint32 pid_mid;
15533         conversation_t *conversation;
15534         nstime_t ns;
15535
15536         si_counter++;
15537         if(si_counter==20){
15538                 si_counter=0;
15539         }
15540         si=&si_arr[si_counter];
15541
15542         top_tree=parent_tree;
15543
15544         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
15545                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
15546         }
15547         if (check_col(pinfo->cinfo, COL_INFO)){
15548                 col_clear(pinfo->cinfo, COL_INFO);
15549         }
15550
15551         /* start off using the local variable, we will allocate a new one if we
15552            need to*/
15553         si->cmd = tvb_get_guint8(tvb, offset+4);
15554         flags = tvb_get_guint8(tvb, offset+9);
15555         si->request = !(flags&SMB_FLAGS_DIRN);
15556         flags2 = tvb_get_letohs(tvb, offset+10);
15557         if(flags2 & 0x8000){
15558                 si->unicode = TRUE; /* Mark them as Unicode */
15559         } else {
15560                 si->unicode = FALSE;
15561         }
15562         si->tid = tvb_get_letohs(tvb, offset+24);
15563         si->pid = tvb_get_letohs(tvb, offset+26);
15564         si->uid = tvb_get_letohs(tvb, offset+28);
15565         si->mid = tvb_get_letohs(tvb, offset+30);
15566         pid_mid = (si->pid << 16) | si->mid;
15567         si->info_level = -1;
15568         si->info_count = -1;
15569
15570         if (parent_tree) {
15571                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
15572                         -1, FALSE);
15573                 tree = proto_item_add_subtree(item, ett_smb);
15574
15575                 hitem = proto_tree_add_text(tree, tvb, offset, 32,
15576                         "SMB Header");
15577
15578                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
15579         }
15580
15581         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
15582         offset += 4;  /* Skip the marker */
15583
15584         /* find which conversation we are part of and get the tables for that
15585            conversation*/
15586         conversation = find_conversation(&pinfo->src, &pinfo->dst,
15587                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
15588         if(!conversation){
15589                 /* OK this is a new conversation so lets create it */
15590                 conversation = conversation_new(&pinfo->src, &pinfo->dst,
15591                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
15592         }
15593         /* see if we already have the smb data for this conversation */
15594         si->ct=conversation_get_proto_data(conversation, proto_smb);
15595         if(!si->ct){
15596                 /* No, not yet. create it and attach it to the conversation */
15597                 si->ct = g_mem_chunk_alloc(conv_tables_chunk);
15598                 conv_tables = g_slist_prepend(conv_tables, si->ct);
15599                 si->ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
15600                         smb_saved_info_equal_matched);
15601                 si->ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
15602                         smb_saved_info_equal_unmatched);
15603                 si->ct->dcerpc_fid_to_frame=g_hash_table_new(
15604                         smb_saved_info_hash_unmatched,
15605                         smb_saved_info_equal_unmatched);
15606                 si->ct->dcerpc_frame_to_dcerpc_pdu=g_hash_table_new(
15607                         smb_saved_info_hash_unmatched,
15608                         smb_saved_info_equal_unmatched);
15609                 si->ct->tid_service=g_hash_table_new(
15610                         smb_saved_info_hash_unmatched,
15611                         smb_saved_info_equal_unmatched);
15612                 conversation_add_proto_data(conversation, proto_smb, si->ct);
15613         }
15614
15615         if( (si->request)
15616             &&  (si->mid==0)
15617             &&  (si->uid==0)
15618             &&  (si->pid==0)
15619             &&  (si->tid==0) ){
15620                 /* this is a broadcast SMB packet, there will not be a reply.
15621                    We dont need to do anything
15622                 */
15623                 si->unidir = TRUE;
15624         } else if( (si->cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
15625                    ||(si->cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
15626                    ||(si->cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
15627                    ||(si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
15628                 /* Ok, we got a special request type. This request is either
15629                    an NT Cancel or a continuation relative to a real request
15630                    in an earlier packet.  In either case, we don't expect any
15631                    responses to this packet.  For continuations, any later
15632                    responses we see really just belong to the original request.
15633                    Anyway, we want to remember this packet somehow and
15634                    remember which original request it is associated with so
15635                    we can say nice things such as "This is a Cancellation to
15636                    the request in frame x", but we don't want the
15637                    request/response matching to get messed up.
15638
15639                    The only thing we do in this case is trying to find which original
15640                    request we match with and insert an entry for this "special"
15641                    request for later reference. We continue to reference the original
15642                    requests smb_saved_info_t but we dont touch it or change anything
15643                    in it.
15644                 */
15645
15646                 si->unidir = TRUE;  /*we dont expect an answer to this one*/
15647
15648                 if(!pinfo->fd->flags.visited){
15649                         /* try to find which original call we match and if we
15650                            find it add us to the matched table. Dont touch
15651                            anything else since we dont want this one to mess
15652                            up the request/response matching. We still consider
15653                            the initial call the real request and this is only
15654                            some sort of continuation.
15655                         */
15656                         /* we only check the unmatched table and assume that the
15657                            last seen MID matching ours is the right one.
15658                            This can fail but is better than nothing
15659                         */
15660                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
15661                         if(sip!=NULL){
15662                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15663                                 new_key->frame = pinfo->fd->num;
15664                                 new_key->pid_mid = pid_mid;
15665                                 g_hash_table_insert(si->ct->matched, new_key,
15666                                     sip);
15667                         }
15668                 } else {
15669                         /* we have seen this packet before; check the
15670                            matching table
15671                         */
15672                         key.frame = pinfo->fd->num;
15673                         key.pid_mid = pid_mid;
15674                         sip=g_hash_table_lookup(si->ct->matched, &key);
15675                         if(sip==NULL){
15676                         /*
15677                           We didn't find it.
15678                           Too bad, unfortunately there is not really much we can
15679                           do now since this means that we never saw the initial
15680                           request.
15681                          */
15682                         }
15683                 }
15684
15685
15686                 if(sip && sip->frame_req){
15687                         switch(si->cmd){
15688                         case SMB_COM_NT_CANCEL:
15689                                 proto_tree_add_uint(htree, hf_smb_cancel_to,
15690                                                     tvb, 0, 0, sip->frame_req);
15691                                 break;
15692                         case SMB_COM_TRANSACTION_SECONDARY:
15693                         case SMB_COM_TRANSACTION2_SECONDARY:
15694                         case SMB_COM_NT_TRANSACT_SECONDARY:
15695                                 proto_tree_add_uint(htree, hf_smb_continuation_to,
15696                                                     tvb, 0, 0, sip->frame_req);
15697                                 break;
15698                         }
15699                 } else {
15700                         switch(si->cmd){
15701                         case SMB_COM_NT_CANCEL:
15702                                 proto_tree_add_text(htree, tvb, 0, 0,
15703                                                     "Cancellation to: <unknown frame>");
15704                                 break;
15705                         case SMB_COM_TRANSACTION_SECONDARY:
15706                         case SMB_COM_TRANSACTION2_SECONDARY:
15707                         case SMB_COM_NT_TRANSACT_SECONDARY:
15708                                 proto_tree_add_text(htree, tvb, 0, 0,
15709                                                     "Continuation to: <unknown frame>");
15710                                 break;
15711                         }
15712                 }
15713         } else { /* normal bidirectional request or response */
15714                 si->unidir = FALSE;
15715
15716                 if(!pinfo->fd->flags.visited){
15717                         /* first see if we find an unmatched smb "equal" to
15718                            the current one
15719                         */
15720                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
15721                         if(sip!=NULL){
15722                                 gboolean cmd_match=FALSE;
15723
15724                                 /*
15725                                  * Make sure the SMB we found was the
15726                                  * same command, or a different command
15727                                  * that's another valid type of reply
15728                                  * to that command.
15729                                  */
15730                                 if(si->cmd==sip->cmd){
15731                                         cmd_match=TRUE;
15732                                 }
15733                                 else if(si->cmd==SMB_COM_NT_CANCEL){
15734                                         cmd_match=TRUE;
15735                                 }
15736                                 else if((si->cmd==SMB_COM_TRANSACTION_SECONDARY)
15737                                      && (sip->cmd==SMB_COM_TRANSACTION)){
15738                                         cmd_match=TRUE;
15739                                 }
15740                                 else if((si->cmd==SMB_COM_TRANSACTION2_SECONDARY)
15741                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
15742                                         cmd_match=TRUE;
15743                                 }
15744                                 else if((si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)
15745                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
15746                                         cmd_match=TRUE;
15747                                 }
15748
15749                                 if( (si->request) || (!cmd_match) ) {
15750                                         /* If we are processing an SMB request but there was already
15751                                            another "identical" smb resuest we had not matched yet.
15752                                            This must mean that either we have a retransmission or that the
15753                                            response to the previous one was lost and the client has reused
15754                                            the MID for this conversation. In either case it's not much more
15755                                            we can do than forget the old request and concentrate on the
15756                                            present one instead.
15757
15758                                            We also do this cleanup if we see that the cmd in the original
15759                                            request in sip->cmd is not compatible with the current cmd.
15760                                            This is to prevent matching errors such as if there were two
15761                                            SMBs of different cmds but with identical MID and PID values and
15762                                            if ethereal lost the first reply and the second request.
15763                                         */
15764                                         g_hash_table_remove(si->ct->unmatched, (void *)pid_mid);
15765                                         sip=NULL; /* XXX should free it as well */
15766                                 } else {
15767                                         /* we have found a response to some request we have seen earlier.
15768                                            What we do now depends on whether this is the first response
15769                                            to that request we see (id frame_res==0) or not.
15770                                         */
15771                                         if(sip->frame_res==0){
15772                                                 /* ok it is the first response we have seen to this packet */
15773                                                 sip->frame_res = pinfo->fd->num;
15774                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15775                                                 new_key->frame = sip->frame_res;
15776                                                 new_key->pid_mid = pid_mid;
15777                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
15778                                         } else {
15779                                                 /* we have already seen another response to this one, but
15780                                                    register it anyway so we see which request it matches
15781                                                 */
15782                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15783                                                 new_key->frame = pinfo->fd->num;
15784                                                 new_key->pid_mid = pid_mid;
15785                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
15786                                         }
15787                                 }
15788                         }
15789                         if(si->request){
15790                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
15791                                 sip->frame_req = pinfo->fd->num;
15792                                 sip->frame_res = 0;
15793                                 sip->req_time.secs=pinfo->fd->abs_secs;
15794                                 sip->req_time.nsecs=pinfo->fd->abs_usecs*1000;
15795                                 sip->flags = 0;
15796                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)
15797                                     == (void *)TID_IPC) {
15798                                         sip->flags |= SMB_SIF_TID_IS_IPC;
15799                                 }
15800                                 sip->cmd = si->cmd;
15801                                 sip->extra_info = NULL;
15802                                 g_hash_table_insert(si->ct->unmatched, (void *)pid_mid, sip);
15803                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15804                                 new_key->frame = sip->frame_req;
15805                                 new_key->pid_mid = pid_mid;
15806                                 g_hash_table_insert(si->ct->matched, new_key, sip);
15807                         }
15808                 } else {
15809                         /* we have seen this packet before; check the
15810                            matching table.
15811                            If we haven't yet seen the reply, we won't
15812                            find the info for it; we don't need it, as
15813                            we only use it to save information, and, as
15814                            we've seen this packet before, we've already
15815                            saved the information.
15816                         */
15817                         key.frame = pinfo->fd->num;
15818                         key.pid_mid = pid_mid;
15819                         sip=g_hash_table_lookup(si->ct->matched, &key);
15820                 }
15821         }
15822
15823         /*
15824          * Pass the "sip" on to subdissectors through "si".
15825          */
15826         si->sip = sip;
15827
15828         if (sip != NULL) {
15829                 /*
15830                  * Put in fields for the frame number of the frame to which
15831                  * this is a response or the frame with the response to this
15832                  * frame - if we know the frame number (i.e., it's not 0).
15833                  */
15834                 if(si->request){
15835                         if (sip->frame_res != 0)
15836                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
15837                 } else {
15838                         if (sip->frame_req != 0) {
15839                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
15840                                 ns.secs = pinfo->fd->abs_secs - sip->req_time.secs;
15841                                 ns.nsecs = pinfo->fd->abs_usecs*1000 - sip->req_time.nsecs;
15842                                 if(ns.nsecs<0){
15843                                         ns.nsecs+=1000000000;
15844                                         ns.secs--;
15845                                 }
15846                                 proto_tree_add_time(htree, hf_smb_time, tvb,
15847                                     0, 0, &ns);
15848                         }
15849                 }
15850         }
15851
15852         /* smb command */
15853         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);
15854         offset += 1;
15855
15856         if(flags2 & 0x4000){
15857                 /* handle NT 32 bit error code */
15858
15859                 nt_status = tvb_get_letohl(tvb, offset);
15860
15861                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
15862                         TRUE);
15863                 offset += 4;
15864
15865         } else {
15866                 /* handle DOS error code & class */
15867                 errclass = tvb_get_guint8(tvb, offset);
15868                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
15869                         errclass);
15870                 offset += 1;
15871
15872                 /* reserved byte */
15873                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
15874                 offset += 1;
15875
15876                 /* error code */
15877                 /* XXX - the type of this field depends on the value of
15878                  * "errcls", so there is isn't a single value_string array
15879                  * fo it, so there can't be a single field for it.
15880                  */
15881                 errcode = tvb_get_letohs(tvb, offset);
15882                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
15883                         offset, 2, errcode, "Error Code: %s",
15884                         decode_smb_error(errclass, errcode));
15885                 offset += 2;
15886         }
15887
15888         /* flags */
15889         offset = dissect_smb_flags(tvb, htree, offset);
15890
15891         /* flags2 */
15892         offset = dissect_smb_flags2(tvb, htree, offset);
15893
15894         /*
15895          * The document at
15896          *
15897          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
15898          *
15899          * (a text version of "Microsoft Networks SMB FILE SHARING
15900          * PROTOCOL, Document Version 6.0p") says that:
15901          *
15902          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
15903          *      the "High Part of PID";
15904          *
15905          *      the next four bytes are reserved;
15906          *
15907          *      the next four bytes are, for SMB-over-IPX (with no
15908          *      NetBIOS involved) two bytes of Session ID and two bytes
15909          *      of SequenceNumber.
15910          *
15911          * Network Monitor 2.x dissects the four bytes before the Session ID
15912          * as a "Key", and the two bytes after the SequenceNumber as
15913          * a "Group ID".
15914          */
15915         if (pinfo->ptype == PT_IPX &&
15916             (pinfo->match_port == IPX_SOCKET_NWLINK_SMB_SERVER ||
15917              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_REDIR ||
15918              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_MESSENGER)) {
15919                 /*
15920                  * This is SMB-over-IPX.
15921                  * XXX - high part of pid?
15922                  * XXX - doe we have to worry about "sequenced commands",
15923                  * as per the Samba document?  They say that for
15924                  * "unsequenced commands" (with a sequence number of 0),
15925                  * the Mid must be unique, but perhaps the Mid doesn't
15926                  * have to be unique for sequenced commands.  In at least
15927                  * one capture with SMB-over-IPX, however, the Mids
15928                  * are unique even for sequenced commands.
15929                  */
15930                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2,
15931                     TRUE);
15932                 offset += 2;
15933
15934                 /* Key */
15935                 proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
15936                     TRUE);
15937                 offset += 4;
15938
15939                 /* Session ID */
15940                 proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
15941                     TRUE);
15942                 offset += 2;
15943
15944                 /* Sequence number */
15945                 proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
15946                     TRUE);
15947                 offset += 2;
15948
15949                 /* Group ID */
15950                 proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
15951                     TRUE);
15952                 offset += 2;
15953         } else {
15954                 /*
15955                  * 12 reserved bytes.
15956                  * XXX - high part of pid?
15957                  */
15958                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 12, TRUE);
15959                 offset += 12;
15960         }
15961
15962         /* TID */
15963         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si->tid);
15964         offset += 2;
15965
15966         /* PID */
15967         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
15968         offset += 2;
15969
15970         /* UID */
15971         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si->uid);
15972         offset += 2;
15973
15974         /* MID */
15975         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
15976         offset += 2;
15977
15978         pinfo->private_data = si;
15979         dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE);
15980
15981         /* Append error info from this packet to info string. */
15982         if (!si->request && check_col(pinfo->cinfo, COL_INFO)) {
15983                 if (flags2 & 0x4000) {
15984                         /*
15985                          * The status is an NT status code; was there
15986                          * an error?
15987                          */
15988                         if ((nt_status & 0xC0000000) == 0xC0000000) {
15989                                 /*
15990                                  * Yes.
15991                                  */
15992                                 col_append_fstr(
15993                                         pinfo->cinfo, COL_INFO, ", Error: %s",
15994                                         val_to_str(nt_status, NT_errors,
15995                                             "Unknown (0x%08X)"));
15996                         }
15997                 } else {
15998                         /*
15999                          * The status is a DOS error class and code; was
16000                          * there an error?
16001                          */
16002                         if (errclass != SMB_SUCCESS) {
16003                                 /*
16004                                  * Yes.
16005                                  */
16006                                 col_append_fstr(
16007                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16008                                         decode_smb_error(errclass, errcode));
16009                         }
16010                 }
16011         }
16012
16013         tap_queue_packet(smb_tap, pinfo, si);
16014 }
16015
16016 static gboolean
16017 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16018 {
16019         /* must check that this really is a smb packet */
16020         if (!tvb_bytes_exist(tvb, 0, 4))
16021                 return FALSE;
16022
16023         if( (tvb_get_guint8(tvb, 0) != 0xff)
16024             || (tvb_get_guint8(tvb, 1) != 'S')
16025             || (tvb_get_guint8(tvb, 2) != 'M')
16026             || (tvb_get_guint8(tvb, 3) != 'B') ){
16027                 return FALSE;
16028         }
16029
16030         dissect_smb(tvb, pinfo, parent_tree);
16031         return TRUE;
16032 }
16033
16034 void
16035 proto_register_smb(void)
16036 {
16037         static hf_register_info hf[] = {
16038         { &hf_smb_cmd,
16039                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
16040                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
16041
16042         { &hf_smb_word_count,
16043                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
16044                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
16045
16046         { &hf_smb_byte_count,
16047                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
16048                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
16049
16050         { &hf_smb_response_to,
16051                 { "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
16052                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
16053
16054         { &hf_smb_time,
16055                 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
16056                 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
16057
16058         { &hf_smb_response_in,
16059                 { "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
16060                 NULL, 0, "The response to this packet is in this packet", HFILL }},
16061
16062         { &hf_smb_continuation_to,
16063                 { "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
16064                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
16065
16066         { &hf_smb_nt_status,
16067                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
16068                 VALS(NT_errors), 0, "NT Status code", HFILL }},
16069
16070         { &hf_smb_error_class,
16071                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
16072                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
16073
16074         { &hf_smb_error_code,
16075                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
16076                 NULL, 0, "DOS Error Code", HFILL }},
16077
16078         { &hf_smb_reserved,
16079                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
16080                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
16081
16082         { &hf_smb_key,
16083                 { "Key", "smb.key", FT_UINT32, BASE_HEX,
16084                 NULL, 0, "SMB-over-IPX Key", HFILL }},
16085
16086         { &hf_smb_session_id,
16087                 { "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
16088                 NULL, 0, "SMB-over-IPX Session ID", HFILL }},
16089
16090         { &hf_smb_sequence_num,
16091                 { "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
16092                 NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
16093
16094         { &hf_smb_group_id,
16095                 { "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
16096                 NULL, 0, "SMB-over-IPX Group ID", HFILL }},
16097
16098         { &hf_smb_pid,
16099                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
16100                 NULL, 0, "Process ID", HFILL }},
16101
16102         { &hf_smb_tid,
16103                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
16104                 NULL, 0, "Tree ID", HFILL }},
16105
16106         { &hf_smb_uid,
16107                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
16108                 NULL, 0, "User ID", HFILL }},
16109
16110         { &hf_smb_mid,
16111                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
16112                 NULL, 0, "Multiplex ID", HFILL }},
16113
16114         { &hf_smb_flags_lock,
16115                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
16116                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
16117
16118         { &hf_smb_flags_receive_buffer,
16119                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
16120                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
16121
16122         { &hf_smb_flags_caseless,
16123                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
16124                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
16125
16126         { &hf_smb_flags_canon,
16127                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
16128                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
16129
16130         { &hf_smb_flags_oplock,
16131                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
16132                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
16133
16134         { &hf_smb_flags_notify,
16135                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
16136                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
16137
16138         { &hf_smb_flags_response,
16139                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
16140                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
16141
16142         { &hf_smb_flags2_long_names_allowed,
16143                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
16144                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
16145
16146         { &hf_smb_flags2_ea,
16147                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
16148                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
16149
16150         { &hf_smb_flags2_sec_sig,
16151                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
16152                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
16153
16154         { &hf_smb_flags2_long_names_used,
16155                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
16156                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
16157
16158         { &hf_smb_flags2_esn,
16159                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
16160                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
16161
16162         { &hf_smb_flags2_dfs,
16163                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
16164                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
16165
16166         { &hf_smb_flags2_roe,
16167                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
16168                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
16169
16170         { &hf_smb_flags2_nt_error,
16171                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
16172                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
16173
16174         { &hf_smb_flags2_string,
16175                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
16176                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
16177
16178         { &hf_smb_buffer_format,
16179                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
16180                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
16181
16182         { &hf_smb_dialect_name,
16183                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
16184                 NULL, 0, "Name of dialect", HFILL }},
16185
16186         { &hf_smb_dialect_index,
16187                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
16188                 NULL, 0, "Index of selected dialect", HFILL }},
16189
16190         { &hf_smb_max_trans_buf_size,
16191                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
16192                 NULL, 0, "Maximum transmit buffer size", HFILL }},
16193
16194         { &hf_smb_max_mpx_count,
16195                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
16196                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
16197
16198         { &hf_smb_max_vcs_num,
16199                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
16200                 NULL, 0, "Maximum VCs between client and server", HFILL }},
16201
16202         { &hf_smb_session_key,
16203                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
16204                 NULL, 0, "Unique token identifying this session", HFILL }},
16205
16206         { &hf_smb_server_timezone,
16207                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
16208                 NULL, 0, "Current timezone at server.", HFILL }},
16209
16210         { &hf_smb_encryption_key_length,
16211                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
16212                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
16213
16214         { &hf_smb_encryption_key,
16215                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
16216                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
16217
16218         { &hf_smb_primary_domain,
16219                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
16220                 NULL, 0, "The server's primary domain", HFILL }},
16221
16222         { &hf_smb_server,
16223                 { "Server", "smb.server", FT_STRING, BASE_NONE,
16224                 NULL, 0, "The name of the DC/server", HFILL }},
16225
16226         { &hf_smb_max_raw_buf_size,
16227                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
16228                 NULL, 0, "Maximum raw buffer size", HFILL }},
16229
16230         { &hf_smb_server_guid,
16231                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
16232                 NULL, 0, "Globally unique identifier for this server", HFILL }},
16233
16234         { &hf_smb_security_blob_len,
16235                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
16236                 NULL, 0, "Security blob length", HFILL }},
16237
16238         { &hf_smb_security_blob,
16239                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
16240                 NULL, 0, "Security blob", HFILL }},
16241
16242         { &hf_smb_sm_mode16,
16243                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
16244                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
16245
16246         { &hf_smb_sm_password16,
16247                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
16248                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
16249
16250         { &hf_smb_sm_mode,
16251                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
16252                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
16253
16254         { &hf_smb_sm_password,
16255                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
16256                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
16257
16258         { &hf_smb_sm_signatures,
16259                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
16260                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
16261
16262         { &hf_smb_sm_sig_required,
16263                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
16264                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
16265
16266         { &hf_smb_rm_read,
16267                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
16268                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
16269
16270         { &hf_smb_rm_write,
16271                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
16272                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
16273
16274         { &hf_smb_server_date_time,
16275                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
16276                 NULL, 0, "Current date and time at server", HFILL }},
16277
16278         { &hf_smb_server_smb_date,
16279                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
16280                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
16281
16282         { &hf_smb_server_smb_time,
16283                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
16284                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
16285
16286         { &hf_smb_server_cap_raw_mode,
16287                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
16288                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
16289
16290         { &hf_smb_server_cap_mpx_mode,
16291                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
16292                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
16293
16294         { &hf_smb_server_cap_unicode,
16295                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
16296                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
16297
16298         { &hf_smb_server_cap_large_files,
16299                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
16300                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
16301
16302         { &hf_smb_server_cap_nt_smbs,
16303                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
16304                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
16305
16306         { &hf_smb_server_cap_rpc_remote_apis,
16307                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
16308                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
16309
16310         { &hf_smb_server_cap_nt_status,
16311                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
16312                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
16313
16314         { &hf_smb_server_cap_level_ii_oplocks,
16315                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
16316                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
16317
16318         { &hf_smb_server_cap_lock_and_read,
16319                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
16320                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
16321
16322         { &hf_smb_server_cap_nt_find,
16323                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
16324                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
16325
16326         { &hf_smb_server_cap_dfs,
16327                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
16328                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
16329
16330         { &hf_smb_server_cap_infolevel_passthru,
16331                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
16332                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
16333
16334         { &hf_smb_server_cap_large_readx,
16335                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
16336                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
16337
16338         { &hf_smb_server_cap_large_writex,
16339                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
16340                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
16341
16342         { &hf_smb_server_cap_unix,
16343                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
16344                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
16345
16346         { &hf_smb_server_cap_reserved,
16347                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
16348                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
16349
16350         { &hf_smb_server_cap_bulk_transfer,
16351                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
16352                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
16353
16354         { &hf_smb_server_cap_compressed_data,
16355                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
16356                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
16357
16358         { &hf_smb_server_cap_extended_security,
16359                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
16360                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
16361
16362         { &hf_smb_system_time,
16363                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
16364                 NULL, 0, "System Time", HFILL }},
16365
16366         { &hf_smb_unknown,
16367                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
16368                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
16369
16370         { &hf_smb_dir_name,
16371                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
16372                 NULL, 0, "SMB Directory Name", HFILL }},
16373
16374         { &hf_smb_echo_count,
16375                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
16376                 NULL, 0, "Number of times to echo data back", HFILL }},
16377
16378         { &hf_smb_echo_data,
16379                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
16380                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
16381
16382         { &hf_smb_echo_seq_num,
16383                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
16384                 NULL, 0, "Sequence number for this echo response", HFILL }},
16385
16386         { &hf_smb_max_buf_size,
16387                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
16388                 NULL, 0, "Max client buffer size", HFILL }},
16389
16390         { &hf_smb_path,
16391                 { "Path", "smb.path", FT_STRING, BASE_NONE,
16392                 NULL, 0, "Path. Server name and share name", HFILL }},
16393
16394         { &hf_smb_service,
16395                 { "Service", "smb.service", FT_STRING, BASE_NONE,
16396                 NULL, 0, "Service name", HFILL }},
16397
16398         { &hf_smb_password,
16399                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
16400                 NULL, 0, "Password", HFILL }},
16401
16402         { &hf_smb_ansi_password,
16403                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
16404                 NULL, 0, "ANSI Password", HFILL }},
16405
16406         { &hf_smb_unicode_password,
16407                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
16408                 NULL, 0, "Unicode Password", HFILL }},
16409
16410         { &hf_smb_move_flags_file,
16411                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
16412                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
16413
16414         { &hf_smb_move_flags_dir,
16415                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
16416                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
16417
16418         { &hf_smb_move_flags_verify,
16419                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
16420                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
16421
16422         { &hf_smb_files_moved,
16423                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
16424                 NULL, 0, "Number of files moved", HFILL }},
16425
16426         { &hf_smb_copy_flags_file,
16427                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
16428                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
16429
16430         { &hf_smb_copy_flags_dir,
16431                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
16432                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
16433
16434         { &hf_smb_copy_flags_dest_mode,
16435                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
16436                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
16437
16438         { &hf_smb_copy_flags_source_mode,
16439                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
16440                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
16441
16442         { &hf_smb_copy_flags_verify,
16443                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
16444                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
16445
16446         { &hf_smb_copy_flags_tree_copy,
16447                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
16448                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
16449
16450         { &hf_smb_copy_flags_ea_action,
16451                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
16452                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
16453
16454         { &hf_smb_count,
16455                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
16456                 NULL, 0, "Count number of items/bytes", HFILL }},
16457
16458         { &hf_smb_file_name,
16459                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
16460                 NULL, 0, "File Name", HFILL }},
16461
16462         { &hf_smb_open_function_create,
16463                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
16464                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
16465
16466         { &hf_smb_open_function_open,
16467                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
16468                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
16469
16470         { &hf_smb_fid,
16471                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
16472                 NULL, 0, "FID: File ID", HFILL }},
16473
16474         { &hf_smb_file_attr_read_only_16bit,
16475                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
16476                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16477
16478         { &hf_smb_file_attr_read_only_8bit,
16479                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
16480                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16481
16482         { &hf_smb_file_attr_hidden_16bit,
16483                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
16484                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16485
16486         { &hf_smb_file_attr_hidden_8bit,
16487                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
16488                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16489
16490         { &hf_smb_file_attr_system_16bit,
16491                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
16492                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16493
16494         { &hf_smb_file_attr_system_8bit,
16495                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
16496                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16497
16498         { &hf_smb_file_attr_volume_16bit,
16499                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
16500                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
16501
16502         { &hf_smb_file_attr_volume_8bit,
16503                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
16504                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
16505
16506         { &hf_smb_file_attr_directory_16bit,
16507                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
16508                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16509
16510         { &hf_smb_file_attr_directory_8bit,
16511                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
16512                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16513
16514         { &hf_smb_file_attr_archive_16bit,
16515                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
16516                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16517
16518         { &hf_smb_file_attr_archive_8bit,
16519                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
16520                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16521
16522         { &hf_smb_file_attr_device,
16523                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
16524                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
16525
16526         { &hf_smb_file_attr_normal,
16527                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
16528                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
16529
16530         { &hf_smb_file_attr_temporary,
16531                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
16532                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
16533
16534         { &hf_smb_file_attr_sparse,
16535                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
16536                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
16537
16538         { &hf_smb_file_attr_reparse,
16539                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
16540                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
16541
16542         { &hf_smb_file_attr_compressed,
16543                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
16544                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
16545
16546         { &hf_smb_file_attr_offline,
16547                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
16548                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
16549
16550         { &hf_smb_file_attr_not_content_indexed,
16551                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
16552                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
16553
16554         { &hf_smb_file_attr_encrypted,
16555                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
16556                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
16557
16558         { &hf_smb_file_size,
16559                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
16560                 NULL, 0, "File Size", HFILL }},
16561
16562         { &hf_smb_search_attribute_read_only,
16563                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
16564                 TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
16565
16566         { &hf_smb_search_attribute_hidden,
16567                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
16568                 TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
16569
16570         { &hf_smb_search_attribute_system,
16571                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
16572                 TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
16573
16574         { &hf_smb_search_attribute_volume,
16575                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
16576                 TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
16577
16578         { &hf_smb_search_attribute_directory,
16579                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
16580                 TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
16581
16582         { &hf_smb_search_attribute_archive,
16583                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
16584                 TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
16585
16586         { &hf_smb_access_mode,
16587                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
16588                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
16589
16590         { &hf_smb_access_sharing,
16591                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
16592                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
16593
16594         { &hf_smb_access_locality,
16595                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
16596                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
16597
16598         { &hf_smb_access_caching,
16599                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
16600                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
16601
16602         { &hf_smb_access_writetru,
16603                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
16604                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
16605
16606         { &hf_smb_create_time,
16607                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
16608                 NULL, 0, "Creation Time", HFILL }},
16609
16610         { &hf_smb_modify_time,
16611                 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
16612                   NULL, 0, "Modification Time", HFILL }},
16613
16614         { &hf_smb_backup_time,
16615                 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
16616                   NULL, 0, "Backup time", HFILL}},
16617
16618         { &hf_smb_mac_alloc_block_count,
16619                 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
16620                   NULL, 0, "Allocation Block Count", HFILL}},
16621
16622         { &hf_smb_mac_alloc_block_size,
16623                 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
16624                   NULL, 0, "Allocation Block Size", HFILL}},
16625
16626         { &hf_smb_mac_free_block_count,
16627                 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
16628                   NULL, 0, "Free Block Count", HFILL}},
16629
16630         { &hf_smb_mac_root_file_count,
16631                 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
16632                 NULL, 0, "Root File Count", HFILL}},
16633
16634         { &hf_smb_mac_root_dir_count,
16635           { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
16636             NULL, 0, "Root Directory Count", HFILL}},
16637
16638         { &hf_smb_mac_file_count,
16639           { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
16640             NULL, 0, "File Count", HFILL}},
16641
16642         { &hf_smb_mac_dir_count,
16643           { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
16644             NULL, 0, "Directory Count", HFILL}},
16645
16646         { &hf_smb_mac_support_flags,
16647           { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
16648             NULL, 0, "Mac Support Flags", HFILL}},
16649
16650         { &hf_smb_mac_sup_access_ctrl,
16651           { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
16652             TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
16653
16654         { &hf_smb_mac_sup_getset_comments,
16655           { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
16656             TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
16657
16658         { &hf_smb_mac_sup_desktopdb_calls,
16659           { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
16660             TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
16661
16662         { &hf_smb_mac_sup_unique_ids,
16663           { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
16664             TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
16665
16666         { &hf_smb_mac_sup_streams,
16667           { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
16668             TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
16669
16670         { &hf_smb_create_dos_date,
16671                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
16672                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
16673
16674         { &hf_smb_create_dos_time,
16675                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
16676                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
16677
16678         { &hf_smb_last_write_time,
16679                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
16680                 NULL, 0, "Time this file was last written to", HFILL }},
16681
16682         { &hf_smb_last_write_dos_date,
16683                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
16684                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
16685
16686         { &hf_smb_last_write_dos_time,
16687                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
16688                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
16689
16690         { &hf_smb_old_file_name,
16691                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
16692                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
16693
16694         { &hf_smb_offset,
16695                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
16696                 NULL, 0, "Offset in file", HFILL }},
16697
16698         { &hf_smb_remaining,
16699                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
16700                 NULL, 0, "Remaining number of bytes", HFILL }},
16701
16702         { &hf_smb_padding,
16703                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
16704                 NULL, 0, "Padding or unknown data", HFILL }},
16705
16706         { &hf_smb_file_data,
16707                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
16708                 NULL, 0, "Data read/written to the file", HFILL }},
16709
16710         { &hf_smb_mac_fndrinfo,
16711                 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_HEX,
16712                   NULL, 0, "Finder Info", HFILL}},
16713
16714         { &hf_smb_total_data_len,
16715                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
16716                 NULL, 0, "Total length of data", HFILL }},
16717
16718         { &hf_smb_data_len,
16719                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
16720                 NULL, 0, "Length of data", HFILL }},
16721
16722         { &hf_smb_seek_mode,
16723                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
16724                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
16725
16726         { &hf_smb_access_time,
16727                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
16728                 NULL, 0, "Last Access Time", HFILL }},
16729
16730         { &hf_smb_access_dos_date,
16731                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
16732                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
16733
16734         { &hf_smb_access_dos_time,
16735                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
16736                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
16737
16738         { &hf_smb_data_size,
16739                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
16740                 NULL, 0, "Data Size", HFILL }},
16741
16742         { &hf_smb_alloc_size,
16743                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
16744                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
16745
16746         { &hf_smb_max_count,
16747                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
16748                 NULL, 0, "Maximum Count", HFILL }},
16749
16750         { &hf_smb_min_count,
16751                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
16752                 NULL, 0, "Minimum Count", HFILL }},
16753
16754         { &hf_smb_timeout,
16755                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
16756                 NULL, 0, "Timeout in miliseconds", HFILL }},
16757
16758         { &hf_smb_high_offset,
16759                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
16760                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
16761
16762         { &hf_smb_units,
16763                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
16764                 NULL, 0, "Total number of units at server", HFILL }},
16765
16766         { &hf_smb_bpu,
16767                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
16768                 NULL, 0, "Blocks per unit at server", HFILL }},
16769
16770         { &hf_smb_blocksize,
16771                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
16772                 NULL, 0, "Block size (in bytes) at server", HFILL }},
16773
16774         { &hf_smb_freeunits,
16775                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
16776                 NULL, 0, "Number of free units at server", HFILL }},
16777
16778         { &hf_smb_data_offset,
16779                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
16780                 NULL, 0, "Data Offset", HFILL }},
16781
16782         { &hf_smb_dcm,
16783                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
16784                 NULL, 0, "Data Compaction Mode", HFILL }},
16785
16786         { &hf_smb_request_mask,
16787                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
16788                 NULL, 0, "Connectionless mode mask", HFILL }},
16789
16790         { &hf_smb_response_mask,
16791                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
16792                 NULL, 0, "Connectionless mode mask", HFILL }},
16793
16794         { &hf_smb_search_id,
16795                 { "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
16796                 NULL, 0, "Search ID, handle for find operations", HFILL }},
16797
16798         { &hf_smb_write_mode_write_through,
16799                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
16800                 TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
16801
16802         { &hf_smb_write_mode_return_remaining,
16803                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
16804                 TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
16805
16806         { &hf_smb_write_mode_raw,
16807                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
16808                 TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
16809
16810         { &hf_smb_write_mode_message_start,
16811                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
16812                 TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
16813
16814         { &hf_smb_write_mode_connectionless,
16815                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
16816                 TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
16817
16818         { &hf_smb_resume_key_len,
16819                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
16820                 NULL, 0, "Resume Key length", HFILL }},
16821
16822         { &hf_smb_resume_find_id,
16823                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
16824                 NULL, 0, "Handle for Find operation", HFILL }},
16825
16826         { &hf_smb_resume_server_cookie,
16827                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
16828                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
16829
16830         { &hf_smb_resume_client_cookie,
16831                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
16832                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
16833
16834         { &hf_smb_andxoffset,
16835                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
16836                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
16837
16838         { &hf_smb_lock_type_large,
16839                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
16840                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
16841
16842         { &hf_smb_lock_type_cancel,
16843                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
16844                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
16845
16846         { &hf_smb_lock_type_change,
16847                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
16848                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
16849
16850         { &hf_smb_lock_type_oplock,
16851                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
16852                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
16853
16854         { &hf_smb_lock_type_shared,
16855                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
16856                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
16857
16858         { &hf_smb_locking_ol,
16859                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
16860                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
16861
16862         { &hf_smb_number_of_locks,
16863                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
16864                 NULL, 0, "Number of lock requests in this request", HFILL }},
16865
16866         { &hf_smb_number_of_unlocks,
16867                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
16868                 NULL, 0, "Number of unlock requests in this request", HFILL }},
16869
16870         { &hf_smb_lock_long_length,
16871                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
16872                 NULL, 0, "Length of lock/unlock region", HFILL }},
16873
16874         { &hf_smb_lock_long_offset,
16875                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
16876                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
16877
16878         { &hf_smb_file_type,
16879                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
16880                 VALS(filetype_vals), 0, "Type of file", HFILL }},
16881
16882         { &hf_smb_ipc_state_nonblocking,
16883                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
16884                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
16885
16886         { &hf_smb_ipc_state_endpoint,
16887                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
16888                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
16889
16890         { &hf_smb_ipc_state_pipe_type,
16891                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
16892                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
16893
16894         { &hf_smb_ipc_state_read_mode,
16895                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
16896                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
16897
16898         { &hf_smb_ipc_state_icount,
16899                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
16900                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
16901
16902         { &hf_smb_server_fid,
16903                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
16904                 NULL, 0, "Server unique File ID", HFILL }},
16905
16906         { &hf_smb_open_flags_add_info,
16907                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
16908                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
16909
16910         { &hf_smb_open_flags_ex_oplock,
16911                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
16912                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
16913
16914         { &hf_smb_open_flags_batch_oplock,
16915                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
16916                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
16917
16918         { &hf_smb_open_flags_ealen,
16919                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
16920                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
16921
16922         { &hf_smb_open_action_open,
16923                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
16924                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
16925
16926         { &hf_smb_open_action_lock,
16927                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
16928                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
16929
16930         { &hf_smb_vc_num,
16931                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
16932                 NULL, 0, "VC Number", HFILL }},
16933
16934         { &hf_smb_password_len,
16935                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
16936                 NULL, 0, "Length of password", HFILL }},
16937
16938         { &hf_smb_ansi_password_len,
16939                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
16940                 NULL, 0, "Length of ANSI password", HFILL }},
16941
16942         { &hf_smb_unicode_password_len,
16943                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
16944                 NULL, 0, "Length of Unicode password", HFILL }},
16945
16946         { &hf_smb_account,
16947                 { "Account", "smb.account", FT_STRING, BASE_NONE,
16948                 NULL, 0, "Account, username", HFILL }},
16949
16950         { &hf_smb_os,
16951                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
16952                 NULL, 0, "Which OS we are running", HFILL }},
16953
16954         { &hf_smb_lanman,
16955                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
16956                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
16957
16958         { &hf_smb_setup_action_guest,
16959                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
16960                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
16961
16962         { &hf_smb_fs,
16963                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
16964                 NULL, 0, "Native File System", HFILL }},
16965
16966         { &hf_smb_connect_flags_dtid,
16967                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
16968                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
16969
16970         { &hf_smb_connect_support_search,
16971                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
16972                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
16973
16974         { &hf_smb_connect_support_in_dfs,
16975                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
16976                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
16977
16978         { &hf_smb_max_setup_count,
16979                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
16980                 NULL, 0, "Maximum number of setup words to return", HFILL }},
16981
16982         { &hf_smb_total_param_count,
16983                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
16984                 NULL, 0, "Total number of parameter bytes", HFILL }},
16985
16986         { &hf_smb_total_data_count,
16987                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
16988                 NULL, 0, "Total number of data bytes", HFILL }},
16989
16990         { &hf_smb_max_param_count,
16991                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
16992                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
16993
16994         { &hf_smb_max_data_count,
16995                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
16996                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
16997
16998         { &hf_smb_param_disp16,
16999                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
17000                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17001
17002         { &hf_smb_param_count16,
17003                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
17004                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17005
17006         { &hf_smb_param_offset16,
17007                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
17008                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17009
17010         { &hf_smb_param_disp32,
17011                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
17012                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17013
17014         { &hf_smb_param_count32,
17015                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
17016                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17017
17018         { &hf_smb_param_offset32,
17019                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
17020                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17021
17022         { &hf_smb_data_count16,
17023                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
17024                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17025
17026         { &hf_smb_data_disp16,
17027                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
17028                 NULL, 0, "Data Displacement", HFILL }},
17029
17030         { &hf_smb_data_offset16,
17031                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17032                 NULL, 0, "Data Offset", HFILL }},
17033
17034         { &hf_smb_data_count32,
17035                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
17036                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17037
17038         { &hf_smb_data_disp32,
17039                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
17040                 NULL, 0, "Data Displacement", HFILL }},
17041
17042         { &hf_smb_data_offset32,
17043                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
17044                 NULL, 0, "Data Offset", HFILL }},
17045
17046         { &hf_smb_setup_count,
17047                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
17048                 NULL, 0, "Number of setup words in this buffer", HFILL }},
17049
17050         { &hf_smb_nt_trans_subcmd,
17051                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
17052                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
17053
17054         { &hf_smb_nt_ioctl_function_code,
17055                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
17056                 NULL, 0, "NT IOCTL function code", HFILL }},
17057
17058         { &hf_smb_nt_ioctl_isfsctl,
17059                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
17060                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
17061
17062         { &hf_smb_nt_ioctl_flags_root_handle,
17063                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
17064                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
17065
17066         { &hf_smb_nt_ioctl_data,
17067                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
17068                 NULL, 0, "Data for the IOCTL call", HFILL }},
17069
17070         { &hf_smb_nt_notify_action,
17071                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
17072                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
17073
17074         { &hf_smb_nt_notify_watch_tree,
17075                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
17076                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
17077
17078         { &hf_smb_nt_notify_stream_write,
17079                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
17080                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
17081
17082         { &hf_smb_nt_notify_stream_size,
17083                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
17084                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
17085
17086         { &hf_smb_nt_notify_stream_name,
17087                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
17088                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
17089
17090         { &hf_smb_nt_notify_security,
17091                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
17092                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
17093
17094         { &hf_smb_nt_notify_ea,
17095                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
17096                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
17097
17098         { &hf_smb_nt_notify_creation,
17099                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
17100                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
17101
17102         { &hf_smb_nt_notify_last_access,
17103                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
17104                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
17105
17106         { &hf_smb_nt_notify_last_write,
17107                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
17108                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
17109
17110         { &hf_smb_nt_notify_size,
17111                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
17112                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
17113
17114         { &hf_smb_nt_notify_attributes,
17115                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
17116                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
17117
17118         { &hf_smb_nt_notify_dir_name,
17119                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
17120                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
17121
17122         { &hf_smb_nt_notify_file_name,
17123                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
17124                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
17125
17126         { &hf_smb_root_dir_fid,
17127                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
17128                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
17129
17130         { &hf_smb_alloc_size64,
17131                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
17132                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17133
17134         { &hf_smb_nt_create_disposition,
17135                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
17136                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
17137
17138         { &hf_smb_sd_length,
17139                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
17140                 NULL, 0, "Total length of security descriptor", HFILL }},
17141
17142         { &hf_smb_ea_length,
17143                 { "EA Length", "smb.ea.length", FT_UINT32, BASE_DEC,
17144                 NULL, 0, "Total EA length for opened file", HFILL }},
17145
17146         { &hf_smb_file_name_len,
17147                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
17148                 NULL, 0, "Length of File Name", HFILL }},
17149
17150         { &hf_smb_nt_impersonation_level,
17151                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
17152                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
17153
17154         { &hf_smb_nt_security_flags_context_tracking,
17155                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
17156                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
17157
17158         { &hf_smb_nt_security_flags_effective_only,
17159                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
17160                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
17161
17162         { &hf_smb_nt_access_mask_generic_read,
17163                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
17164                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
17165
17166         { &hf_smb_nt_access_mask_generic_write,
17167                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
17168                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
17169
17170         { &hf_smb_nt_access_mask_generic_execute,
17171                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
17172                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
17173
17174         { &hf_smb_nt_access_mask_generic_all,
17175                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
17176                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
17177
17178         { &hf_smb_nt_access_mask_maximum_allowed,
17179                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
17180                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
17181
17182         { &hf_smb_nt_access_mask_system_security,
17183                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
17184                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
17185
17186         { &hf_smb_nt_access_mask_synchronize,
17187                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
17188                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
17189
17190         { &hf_smb_nt_access_mask_write_owner,
17191                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
17192                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
17193
17194         { &hf_smb_nt_access_mask_write_dac,
17195                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
17196                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
17197
17198         { &hf_smb_nt_access_mask_read_control,
17199                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
17200                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
17201
17202         { &hf_smb_nt_access_mask_delete,
17203                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
17204                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
17205
17206         { &hf_smb_nt_access_mask_write_attributes,
17207                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
17208                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
17209
17210         { &hf_smb_nt_access_mask_read_attributes,
17211                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
17212                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
17213
17214         { &hf_smb_nt_access_mask_delete_child,
17215                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
17216                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
17217
17218         /*
17219          * "Execute" for files, "traverse" for directories.
17220          */
17221         { &hf_smb_nt_access_mask_execute,
17222                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
17223                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
17224
17225         { &hf_smb_nt_access_mask_write_ea,
17226                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
17227                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
17228
17229         { &hf_smb_nt_access_mask_read_ea,
17230                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
17231                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
17232
17233         /*
17234          * "Append data" for files, "add subdirectory" for directories,
17235          * "create pipe instance" for named pipes.
17236          */
17237         { &hf_smb_nt_access_mask_append,
17238                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
17239                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
17240
17241         /*
17242          * "Write data" for files and pipes, "add file" for directory.
17243          */
17244         { &hf_smb_nt_access_mask_write,
17245                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
17246                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
17247
17248         /*
17249          * "Read data" for files and pipes, "list directory" for directory.
17250          */
17251         { &hf_smb_nt_access_mask_read,
17252                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
17253                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
17254
17255         { &hf_smb_nt_create_bits_oplock,
17256                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
17257                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
17258
17259         { &hf_smb_nt_create_bits_boplock,
17260                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
17261                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
17262
17263         { &hf_smb_nt_create_bits_dir,
17264                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
17265                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
17266
17267         { &hf_smb_nt_create_options_directory_file,
17268                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
17269                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
17270
17271         { &hf_smb_nt_create_options_write_through,
17272                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
17273                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
17274
17275         { &hf_smb_nt_create_options_sequential_only,
17276                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
17277                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
17278
17279         { &hf_smb_nt_create_options_sync_io_alert,
17280                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
17281                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
17282
17283         { &hf_smb_nt_create_options_sync_io_nonalert,
17284                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
17285                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
17286
17287         { &hf_smb_nt_create_options_non_directory_file,
17288                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
17289                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
17290
17291         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
17292            and "NtOpenFile()"; is that sent over the wire?  Network
17293            Monitor thinks so, but its author may just have grabbed
17294            the flag bits from a system header file. */
17295
17296         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
17297            and "NtOpenFile()"; is that sent over the wire?  NetMon
17298            thinks so, but see previous comment. */
17299
17300         { &hf_smb_nt_create_options_no_ea_knowledge,
17301                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
17302                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
17303
17304         { &hf_smb_nt_create_options_eight_dot_three_only,
17305                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
17306                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
17307
17308         { &hf_smb_nt_create_options_random_access,
17309                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
17310                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
17311
17312         { &hf_smb_nt_create_options_delete_on_close,
17313                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
17314                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
17315
17316         /* 0x00002000 is "open by FID", or something such as that (which
17317            I suspect is like "open by inumber" on UNIX), at least in
17318            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
17319            wire?  NetMon thinks so, but see previous comment. */
17320
17321         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
17322            and "NtOpenFile()"; is that sent over the wire?  NetMon
17323            thinks so, but see previous comment. */
17324
17325         { &hf_smb_nt_share_access_read,
17326                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
17327                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
17328
17329         { &hf_smb_nt_share_access_write,
17330                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
17331                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
17332
17333         { &hf_smb_nt_share_access_delete,
17334                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
17335                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
17336
17337         { &hf_smb_file_eattr_read_only,
17338                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
17339                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17340
17341         { &hf_smb_file_eattr_hidden,
17342                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
17343                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17344
17345         { &hf_smb_file_eattr_system,
17346                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
17347                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17348
17349         { &hf_smb_file_eattr_volume,
17350                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
17351                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
17352
17353         { &hf_smb_file_eattr_directory,
17354                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
17355                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17356
17357         { &hf_smb_file_eattr_archive,
17358                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
17359                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17360
17361         { &hf_smb_file_eattr_device,
17362                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
17363                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
17364
17365         { &hf_smb_file_eattr_normal,
17366                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
17367                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
17368
17369         { &hf_smb_file_eattr_temporary,
17370                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
17371                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
17372
17373         { &hf_smb_file_eattr_sparse,
17374                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
17375                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
17376
17377         { &hf_smb_file_eattr_reparse,
17378                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
17379                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
17380
17381         { &hf_smb_file_eattr_compressed,
17382                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
17383                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
17384
17385         { &hf_smb_file_eattr_offline,
17386                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
17387                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
17388
17389         { &hf_smb_file_eattr_not_content_indexed,
17390                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
17391                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
17392
17393         { &hf_smb_file_eattr_encrypted,
17394                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
17395                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
17396
17397         { &hf_smb_sec_desc_len,
17398                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
17399                 NULL, 0, "Security Descriptor Length", HFILL }},
17400
17401         { &hf_smb_nt_qsd_owner,
17402                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
17403                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
17404
17405         { &hf_smb_nt_qsd_group,
17406                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
17407                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
17408
17409         { &hf_smb_nt_qsd_dacl,
17410                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
17411                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
17412
17413         { &hf_smb_nt_qsd_sacl,
17414                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
17415                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
17416
17417         { &hf_smb_extended_attributes,
17418                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
17419                 NULL, 0, "Extended Attributes", HFILL }},
17420
17421         { &hf_smb_oplock_level,
17422                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
17423                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
17424
17425         { &hf_smb_create_action,
17426                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
17427                 VALS(create_disposition_vals), 0, "Type of action taken", HFILL }},
17428
17429         { &hf_smb_file_id,
17430                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
17431                 NULL, 0, "Server unique file ID", HFILL }},
17432
17433         { &hf_smb_ea_error_offset,
17434                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
17435                 NULL, 0, "Offset into EA list if EA error", HFILL }},
17436
17437         { &hf_smb_end_of_file,
17438                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
17439                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
17440
17441         { &hf_smb_device_type,
17442                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
17443                 VALS(device_type_vals), 0, "Type of device", HFILL }},
17444
17445         { &hf_smb_is_directory,
17446                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
17447                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
17448
17449         { &hf_smb_next_entry_offset,
17450                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
17451                 NULL, 0, "Offset to next entry", HFILL }},
17452
17453         { &hf_smb_change_time,
17454                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
17455                 NULL, 0, "Last Change Time", HFILL }},
17456
17457         { &hf_smb_setup_len,
17458                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
17459                 NULL, 0, "Length of printer setup data", HFILL }},
17460
17461         { &hf_smb_print_mode,
17462                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
17463                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
17464
17465         { &hf_smb_print_identifier,
17466                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
17467                 NULL, 0, "Identifier string for this print job", HFILL }},
17468
17469         { &hf_smb_restart_index,
17470                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
17471                 NULL, 0, "Index of entry after last returned", HFILL }},
17472
17473         { &hf_smb_print_queue_date,
17474                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
17475                 NULL, 0, "Date when this entry was queued", HFILL }},
17476
17477         { &hf_smb_print_queue_dos_date,
17478                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
17479                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
17480
17481         { &hf_smb_print_queue_dos_time,
17482                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
17483                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
17484
17485         { &hf_smb_print_status,
17486                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
17487                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
17488
17489         { &hf_smb_print_spool_file_number,
17490                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
17491                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
17492
17493         { &hf_smb_print_spool_file_size,
17494                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
17495                 NULL, 0, "Number of bytes in spool file", HFILL }},
17496
17497         { &hf_smb_print_spool_file_name,
17498                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
17499                 NULL, 0, "Name of client that submitted this job", HFILL }},
17500
17501         { &hf_smb_start_index,
17502                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
17503                 NULL, 0, "First queue entry to return", HFILL }},
17504
17505         { &hf_smb_originator_name,
17506                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
17507                 NULL, 0, "Name of sender of message", HFILL }},
17508
17509         { &hf_smb_destination_name,
17510                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
17511                 NULL, 0, "Name of recipient of message", HFILL }},
17512
17513         { &hf_smb_message_len,
17514                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
17515                 NULL, 0, "Length of message", HFILL }},
17516
17517         { &hf_smb_message,
17518                 { "Message", "smb.message", FT_STRING, BASE_NONE,
17519                 NULL, 0, "Message text", HFILL }},
17520
17521         { &hf_smb_mgid,
17522                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
17523                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
17524
17525         { &hf_smb_forwarded_name,
17526                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
17527                 NULL, 0, "Recipient name being forwarded", HFILL }},
17528
17529         { &hf_smb_machine_name,
17530                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
17531                 NULL, 0, "Name of target machine", HFILL }},
17532
17533         { &hf_smb_cancel_to,
17534                 { "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
17535                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
17536
17537         { &hf_smb_trans2_subcmd,
17538                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
17539                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
17540
17541         { &hf_smb_trans_name,
17542                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
17543                 NULL, 0, "Name of transaction", HFILL }},
17544
17545         { &hf_smb_transaction_flags_dtid,
17546                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
17547                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
17548
17549         { &hf_smb_transaction_flags_owt,
17550                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
17551                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
17552
17553         { &hf_smb_search_count,
17554                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
17555                 NULL, 0, "Maximum number of search entries to return", HFILL }},
17556
17557         { &hf_smb_search_pattern,
17558                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
17559                 NULL, 0, "Search Pattern", HFILL }},
17560
17561         { &hf_smb_ff2_backup,
17562                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
17563                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
17564
17565         { &hf_smb_ff2_continue,
17566                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
17567                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
17568
17569         { &hf_smb_ff2_resume,
17570                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
17571                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
17572
17573         { &hf_smb_ff2_close_eos,
17574                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
17575                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
17576
17577         { &hf_smb_ff2_close,
17578                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
17579                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
17580
17581         { &hf_smb_ff2_information_level,
17582                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
17583                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
17584
17585         { &hf_smb_qpi_loi,
17586                 { "Level of Interest", "smb.loi", FT_UINT16, BASE_DEC,
17587                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] commands", HFILL }},
17588
17589 #if 0
17590         { &hf_smb_sfi_writetru,
17591                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
17592                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
17593
17594         { &hf_smb_sfi_caching,
17595                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
17596                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
17597 #endif
17598
17599         { &hf_smb_storage_type,
17600                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
17601                 NULL, 0, "Type of storage", HFILL }},
17602
17603         { &hf_smb_resume,
17604                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
17605                 NULL, 0, "Resume Key", HFILL }},
17606
17607         { &hf_smb_max_referral_level,
17608                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
17609                 NULL, 0, "Latest referral version number understood", HFILL }},
17610
17611         { &hf_smb_qfsi_information_level,
17612                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_HEX,
17613                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
17614
17615         { &hf_smb_nt_rename_level,
17616                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
17617                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
17618
17619         { &hf_smb_cluster_count,
17620                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
17621                 NULL, 0, "Number of clusters", HFILL }},
17622
17623         { &hf_smb_ea_size,
17624                 { "EA Size", "smb.ea_size", FT_UINT32, BASE_DEC,
17625                 NULL, 0, "Size of file's EA information", HFILL }},
17626
17627         { &hf_smb_list_length,
17628                 { "ListLength", "smb.list_len", FT_UINT32, BASE_DEC,
17629                 NULL, 0, "Length of the remaining data", HFILL }},
17630
17631         { &hf_smb_number_of_links,
17632                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
17633                 NULL, 0, "Number of hard links to the file", HFILL }},
17634
17635         { &hf_smb_delete_pending,
17636                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
17637                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
17638
17639         { &hf_smb_index_number,
17640                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
17641                 NULL, 0, "File system unique identifier", HFILL }},
17642
17643         { &hf_smb_current_offset,
17644                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
17645                 NULL, 0, "Current offset in the file", HFILL }},
17646
17647         { &hf_smb_t2_alignment,
17648                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
17649                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
17650
17651         { &hf_smb_t2_stream_name_length,
17652                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
17653                 NULL, 0, "Length of stream name", HFILL }},
17654
17655         { &hf_smb_t2_stream_size,
17656                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
17657                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
17658
17659         { &hf_smb_t2_stream_name,
17660                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
17661                 NULL, 0, "Name of the stream", HFILL }},
17662
17663         { &hf_smb_t2_compressed_file_size,
17664                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
17665                 NULL, 0, "Size of the compressed file", HFILL }},
17666
17667         { &hf_smb_t2_compressed_format,
17668                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
17669                 NULL, 0, "Compression algorithm used", HFILL }},
17670
17671         { &hf_smb_t2_compressed_unit_shift,
17672                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
17673                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
17674
17675         { &hf_smb_t2_compressed_chunk_shift,
17676                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
17677                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
17678
17679         { &hf_smb_t2_compressed_cluster_shift,
17680                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
17681                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
17682
17683         { &hf_smb_dfs_path_consumed,
17684                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
17685                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
17686
17687         { &hf_smb_dfs_num_referrals,
17688                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
17689                 NULL, 0, "Number of referrals in this pdu", HFILL }},
17690
17691         { &hf_smb_get_dfs_server_hold_storage,
17692                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
17693                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
17694
17695         { &hf_smb_get_dfs_fielding,
17696                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
17697                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
17698
17699         { &hf_smb_dfs_referral_version,
17700                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
17701                 NULL, 0, "Version of referral element", HFILL }},
17702
17703         { &hf_smb_dfs_referral_size,
17704                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
17705                 NULL, 0, "Size of referral element", HFILL }},
17706
17707         { &hf_smb_dfs_referral_server_type,
17708                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
17709                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
17710
17711         { &hf_smb_dfs_referral_flags_strip,
17712                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
17713                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
17714
17715         { &hf_smb_dfs_referral_node_offset,
17716                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
17717                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
17718
17719         { &hf_smb_dfs_referral_node,
17720                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
17721                 NULL, 0, "Name of entity to visit next", HFILL }},
17722
17723         { &hf_smb_dfs_referral_proximity,
17724                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
17725                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
17726
17727         { &hf_smb_dfs_referral_ttl,
17728                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
17729                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
17730
17731         { &hf_smb_dfs_referral_path_offset,
17732                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
17733                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
17734
17735         { &hf_smb_dfs_referral_path,
17736                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
17737                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
17738
17739         { &hf_smb_dfs_referral_alt_path_offset,
17740                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
17741                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
17742
17743         { &hf_smb_dfs_referral_alt_path,
17744                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
17745                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
17746
17747         { &hf_smb_end_of_search,
17748                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
17749                 NULL, 0, "Was last entry returned?", HFILL }},
17750
17751         { &hf_smb_last_name_offset,
17752                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
17753                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
17754
17755         { &hf_smb_fn_information_level,
17756                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
17757                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
17758
17759         { &hf_smb_monitor_handle,
17760                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
17761                 NULL, 0, "Handle for Find Notify operations", HFILL }},
17762
17763         { &hf_smb_change_count,
17764                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
17765                 NULL, 0, "Number of changes to wait for", HFILL }},
17766
17767         { &hf_smb_file_index,
17768                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
17769                 NULL, 0, "File index", HFILL }},
17770
17771         { &hf_smb_short_file_name,
17772                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
17773                 NULL, 0, "Short (8.3) File Name", HFILL }},
17774
17775         { &hf_smb_short_file_name_len,
17776                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
17777                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
17778
17779         { &hf_smb_fs_id,
17780                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
17781                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
17782
17783         { &hf_smb_sector_unit,
17784                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
17785                 NULL, 0, "Sectors per allocation unit", HFILL }},
17786
17787         { &hf_smb_fs_units,
17788                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
17789                 NULL, 0, "Total number of units on this filesystem", HFILL }},
17790
17791         { &hf_smb_fs_sector,
17792                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
17793                 NULL, 0, "Bytes per sector", HFILL }},
17794
17795         { &hf_smb_avail_units,
17796                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
17797                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
17798
17799         { &hf_smb_volume_serial_num,
17800                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
17801                 NULL, 0, "Volume serial number", HFILL }},
17802
17803         { &hf_smb_volume_label_len,
17804                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
17805                 NULL, 0, "Length of volume label", HFILL }},
17806
17807         { &hf_smb_volume_label,
17808                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
17809                 NULL, 0, "Volume label", HFILL }},
17810
17811         { &hf_smb_free_alloc_units64,
17812                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
17813                 NULL, 0, "Number of free allocation units", HFILL }},
17814
17815         { &hf_smb_caller_free_alloc_units64,
17816                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
17817                 NULL, 0, "Number of caller free allocation units", HFILL }},
17818
17819         { &hf_smb_actual_free_alloc_units64,
17820                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
17821                 NULL, 0, "Number of actual free allocation units", HFILL }},
17822
17823         { &hf_smb_soft_quota_limit,
17824                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
17825                 NULL, 0, "Soft Quota treshold", HFILL }},
17826
17827         { &hf_smb_hard_quota_limit,
17828                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
17829                 NULL, 0, "Hard Quota limit", HFILL }},
17830
17831         { &hf_smb_user_quota_used,
17832                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
17833                 NULL, 0, "How much Quota is used by this user", HFILL }},
17834
17835         { &hf_smb_max_name_len,
17836                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
17837                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
17838
17839         { &hf_smb_fs_name_len,
17840                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
17841                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
17842
17843         { &hf_smb_fs_name,
17844                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
17845                 NULL, 0, "Name of filesystem", HFILL }},
17846
17847         { &hf_smb_device_char_removable,
17848                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
17849                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
17850
17851         { &hf_smb_device_char_read_only,
17852                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
17853                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
17854
17855         { &hf_smb_device_char_floppy,
17856                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
17857                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
17858
17859         { &hf_smb_device_char_write_once,
17860                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
17861                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
17862
17863         { &hf_smb_device_char_remote,
17864                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
17865                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
17866
17867         { &hf_smb_device_char_mounted,
17868                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
17869                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
17870
17871         { &hf_smb_device_char_virtual,
17872                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
17873                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
17874
17875         { &hf_smb_fs_attr_css,
17876                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
17877                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
17878
17879         { &hf_smb_fs_attr_cpn,
17880                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
17881                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
17882
17883         { &hf_smb_fs_attr_pacls,
17884                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
17885                 TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
17886
17887         { &hf_smb_fs_attr_fc,
17888                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
17889                 TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
17890
17891         { &hf_smb_fs_attr_vq,
17892                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
17893                 TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
17894
17895         { &hf_smb_fs_attr_dim,
17896                 { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
17897                 TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
17898
17899         { &hf_smb_fs_attr_vic,
17900                 { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
17901                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
17902
17903         { &hf_smb_sec_desc_revision,
17904                 { "Revision", "smb.sec_desc.revision", FT_UINT8, BASE_DEC,
17905                 NULL, 0, "Version of NT Security Descriptor structure", HFILL }},
17906
17907         { &hf_smb_sid,
17908                 { "SID", "smb.sid", FT_STRING, BASE_DEC,
17909                 NULL, 0, "SID: Security Identifier", HFILL }},
17910
17911         { &hf_smb_sid_revision,
17912                 { "Revision", "smb.sid.revision", FT_UINT8, BASE_DEC,
17913                 NULL, 0, "Version of SID structure", HFILL }},
17914
17915         { &hf_smb_sid_num_auth,
17916                 { "Num Auth", "smb.sid.num_auth", FT_UINT8, BASE_DEC,
17917                 NULL, 0, "Number of authorities for this SID", HFILL }},
17918
17919         { &hf_smb_acl_revision,
17920                 { "Revision", "smb.acl.revision", FT_UINT16, BASE_DEC,
17921                 NULL, 0, "Version of NT ACL structure", HFILL }},
17922
17923         { &hf_smb_acl_size,
17924                 { "Size", "smb.acl.size", FT_UINT16, BASE_DEC,
17925                 NULL, 0, "Size of NT ACL structure", HFILL }},
17926
17927         { &hf_smb_acl_num_aces,
17928                 { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
17929                 NULL, 0, "Number of ACE structures for this ACL", HFILL }},
17930
17931         { &hf_smb_user_quota_offset,
17932                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
17933                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
17934
17935         { &hf_smb_ace_type,
17936                 { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
17937                 VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
17938
17939         { &hf_smb_pipe_write_len,
17940                 { "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
17941                 NULL, 0, "Number of bytes written to pipe", HFILL }},
17942
17943         { &hf_smb_ace_size,
17944                 { "Size", "smb.ace.size", FT_UINT16, BASE_DEC,
17945                 NULL, 0, "Size of this ACE", HFILL }},
17946
17947         { &hf_smb_ace_flags_object_inherit,
17948                 { "Object Inherit", "smb.ace.flags.object_inherit", FT_BOOLEAN, 8,
17949                 TFS(&tfs_ace_flags_object_inherit), 0x01, "Will subordinate files inherit this ACE?", HFILL }},
17950
17951         { &hf_smb_ace_flags_container_inherit,
17952                 { "Container Inherit", "smb.ace.flags.container_inherit", FT_BOOLEAN, 8,
17953                 TFS(&tfs_ace_flags_container_inherit), 0x02, "Will subordinate containers inherit this ACE?", HFILL }},
17954
17955         { &hf_smb_ace_flags_non_propagate_inherit,
17956                 { "Non-Propagate Inherit", "smb.ace.flags.non_propagate_inherit", FT_BOOLEAN, 8,
17957                 TFS(&tfs_ace_flags_non_propagate_inherit), 0x04, "Will subordinate object propagate this ACE further?", HFILL }},
17958
17959         { &hf_smb_ace_flags_inherit_only,
17960                 { "Inherit Only", "smb.ace.flags.inherit_only", FT_BOOLEAN, 8,
17961                 TFS(&tfs_ace_flags_inherit_only), 0x08, "Does this ACE apply to the current object?", HFILL }},
17962
17963         { &hf_smb_ace_flags_inherited_ace,
17964                 { "Inherited ACE", "smb.ace.flags.inherited_ace", FT_BOOLEAN, 8,
17965                 TFS(&tfs_ace_flags_inherited_ace), 0x10, "Was this ACE inherited from its parent object?", HFILL }},
17966
17967         { &hf_smb_ace_flags_successful_access,
17968                 { "Audit Successful Accesses", "smb.ace.flags.successful_access", FT_BOOLEAN, 8,
17969                 TFS(&tfs_ace_flags_successful_access), 0x40, "Should successful accesses be audited?", HFILL }},
17970
17971         { &hf_smb_ace_flags_failed_access,
17972                 { "Audit Failed Accesses", "smb.ace.flags.failed_access", FT_BOOLEAN, 8,
17973                 TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
17974
17975         { &hf_smb_sec_desc_type_owner_defaulted,
17976                 { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
17977                 TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
17978
17979         { &hf_smb_sec_desc_type_group_defaulted,
17980                 { "Group Defaulted", "smb.sec_desc.type.group_defaulted", FT_BOOLEAN, 16,
17981                 TFS(&tfs_sec_desc_type_group_defaulted), 0x0002, "Is Group Defaulted?", HFILL }},
17982
17983         { &hf_smb_sec_desc_type_dacl_present,
17984                 { "DACL Present", "smb.sec_desc.type.dacl_present", FT_BOOLEAN, 16,
17985                 TFS(&tfs_sec_desc_type_dacl_present), 0x0004, "Does this SecDesc have DACL present?", HFILL }},
17986
17987         { &hf_smb_sec_desc_type_dacl_defaulted,
17988                 { "DACL Defaulted", "smb.sec_desc.type.dacl_defaulted", FT_BOOLEAN, 16,
17989                 TFS(&tfs_sec_desc_type_dacl_defaulted), 0x0008, "Does this SecDesc have DACL Defaulted?", HFILL }},
17990
17991         { &hf_smb_sec_desc_type_sacl_present,
17992                 { "SACL Present", "smb.sec_desc.type.sacl_present", FT_BOOLEAN, 16,
17993                 TFS(&tfs_sec_desc_type_sacl_present), 0x0010, "Is the SACL present?", HFILL }},
17994
17995         { &hf_smb_sec_desc_type_sacl_defaulted,
17996                 { "SACL Defaulted", "smb.sec_desc.type.sacl_defaulted", FT_BOOLEAN, 16,
17997                 TFS(&tfs_sec_desc_type_sacl_defaulted), 0x0020, "Does this SecDesc have SACL Defaulted?", HFILL }},
17998
17999         { &hf_smb_sec_desc_type_dacl_auto_inherit_req,
18000                 { "DACL Auto Inherit Required", "smb.sec_desc.type.dacl_auto_inherit_req", FT_BOOLEAN, 16,
18001                 TFS(&tfs_sec_desc_type_dacl_auto_inherit_req), 0x0100, "Does this SecDesc have DACL Auto Inherit Required set?", HFILL }},
18002
18003         { &hf_smb_sec_desc_type_sacl_auto_inherit_req,
18004                 { "SACL Auto Inherit Required", "smb.sec_desc.type.sacl_auto_inherit_req", FT_BOOLEAN, 16,
18005                 TFS(&tfs_sec_desc_type_sacl_auto_inherit_req), 0x0200, "Does this SecDesc have SACL Auto Inherit Required set?", HFILL }},
18006
18007         { &hf_smb_sec_desc_type_dacl_auto_inherited,
18008                 { "DACL Auto Inherited", "smb.sec_desc.type.dacl_auto_inherited", FT_BOOLEAN, 16,
18009                 TFS(&tfs_sec_desc_type_dacl_auto_inherited), 0x0400, "Is this DACL auto inherited", HFILL }},
18010
18011         { &hf_smb_sec_desc_type_sacl_auto_inherited,
18012                 { "SACL Auto Inherited", "smb.sec_desc.type.sacl_auto_inherited", FT_BOOLEAN, 16,
18013                 TFS(&tfs_sec_desc_type_sacl_auto_inherited), 0x0800, "Is this SACL auto inherited", HFILL }},
18014
18015         { &hf_smb_sec_desc_type_dacl_protected,
18016                 { "DACL Protected", "smb.sec_desc.type.dacl_protected", FT_BOOLEAN, 16,
18017                 TFS(&tfs_sec_desc_type_dacl_protected), 0x1000, "Is the DACL structure protected?", HFILL }},
18018
18019         { &hf_smb_sec_desc_type_sacl_protected,
18020                 { "SACL Protected", "smb.sec_desc.type.sacl_protected", FT_BOOLEAN, 16,
18021                 TFS(&tfs_sec_desc_type_sacl_protected), 0x2000, "Is the SACL structure protected?", HFILL }},
18022
18023         { &hf_smb_sec_desc_type_self_relative,
18024                 { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
18025                 TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
18026
18027         { &hf_smb_quota_flags_deny_disk,
18028                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
18029                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
18030
18031         { &hf_smb_quota_flags_log_limit,
18032                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
18033                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
18034
18035         { &hf_smb_quota_flags_log_warning,
18036                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
18037                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
18038
18039         { &hf_smb_quota_flags_enabled,
18040                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
18041                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
18042
18043         { &hf_smb_segment_overlap,
18044                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18045                         "Fragment overlaps with other fragments", HFILL }},
18046
18047         { &hf_smb_segment_overlap_conflict,
18048                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18049                         "Overlapping fragments contained conflicting data", HFILL }},
18050
18051         { &hf_smb_segment_multiple_tails,
18052                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18053                         "Several tails were found when defragmenting the packet", HFILL }},
18054
18055         { &hf_smb_segment_too_long_fragment,
18056                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18057                         "Fragment contained data past end of packet", HFILL }},
18058
18059         { &hf_smb_segment_error,
18060                 { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18061                         "Defragmentation error due to illegal fragments", HFILL }},
18062
18063         { &hf_smb_segment,
18064                 { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18065                         "SMB Segment", HFILL }},
18066
18067         { &hf_smb_segments,
18068                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
18069                         "SMB Segments", HFILL }},
18070
18071                 /* Access masks */
18072
18073                 { &hf_smb_access_mask,
18074                   { "Access required", "smb.access_mask",
18075                     FT_UINT32, BASE_HEX, NULL, 0x0, "Access mask",
18076                     HFILL }},
18077                 { &hf_access_generic_read,
18078                   { "Generic read", "nt.access_mask.generic_read",
18079                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18080                     GENERIC_READ_ACCESS, "Generic read", HFILL }},
18081
18082                 { &hf_access_generic_write,
18083                   { "Generic write", "nt.access_mask.generic_write",
18084                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18085                     GENERIC_WRITE_ACCESS, "Generic write", HFILL }},
18086
18087                 { &hf_access_generic_execute,
18088                   { "Generic execute", "nt.access_mask.generic_execute",
18089                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18090                     GENERIC_EXECUTE_ACCESS, "Generic execute", HFILL }},
18091
18092                 { &hf_access_generic_all,
18093                   { "Generic all", "nt.access_mask.generic_all",
18094                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18095                     GENERIC_ALL_ACCESS, "Generic all", HFILL }},
18096
18097                 { &hf_access_maximum_allowed,
18098                   { "Maximum allowed", "nt.access_mask.maximum_allowed",
18099                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18100                     MAXIMUM_ALLOWED_ACCESS, "Maximum allowed", HFILL }},
18101
18102                 { &hf_access_sacl,
18103                   { "Access SACL", "nt.access_mask.access_sacl",
18104                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18105                     ACCESS_SACL_ACCESS, "Access SACL", HFILL }},
18106
18107                 { &hf_access_standard_read_control,
18108                   { "Read control", "nt.access_mask.read_control",
18109                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18110                     READ_CONTROL_ACCESS, "Read control", HFILL }},
18111
18112                 { &hf_access_standard_delete,
18113                   { "Delete", "nt.access_mask.delete",
18114                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18115                     DELETE_ACCESS, "Delete", HFILL }},
18116
18117                 { &hf_access_standard_synchronise,
18118                   { "Synchronise", "nt.access_mask.synchronise",
18119                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18120                     SYNCHRONIZE_ACCESS, "Synchronise", HFILL }},
18121
18122                 { &hf_access_standard_write_dac,
18123                   { "Write DAC", "nt.access_mask.write_dac",
18124                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18125                     WRITE_DAC_ACCESS, "Write DAC", HFILL }},
18126
18127                 { &hf_access_standard_write_owner,
18128                   { "Write owner", "nt.access_mask.write_owner",
18129                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18130                     WRITE_OWNER_ACCESS, "Write owner", HFILL }},
18131
18132                 { &hf_access_specific_15,
18133                   { "Specific access, bit 15", "nt.access_mask.specific_15",
18134                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18135                     0x8000, "Specific access, bit 15", HFILL }},
18136
18137                 { &hf_access_specific_14,
18138                   { "Specific access, bit 14", "nt.access_mask.specific_14",
18139                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18140                     0x4000, "Specific access, bit 14", HFILL }},
18141
18142                 { &hf_access_specific_13,
18143                   { "Specific access, bit 13", "nt.access_mask.specific_13",
18144                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18145                     0x2000, "Specific access, bit 13", HFILL }},
18146
18147                 { &hf_access_specific_12,
18148                   { "Specific access, bit 12", "nt.access_mask.specific_12",
18149                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18150                     0x1000, "Specific access, bit 12", HFILL }},
18151
18152                 { &hf_access_specific_11,
18153                   { "Specific access, bit 11", "nt.access_mask.specific_11",
18154                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18155                     0x0800, "Specific access, bit 11", HFILL }},
18156
18157                 { &hf_access_specific_10,
18158                   { "Specific access, bit 10", "nt.access_mask.specific_10",
18159                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18160                     0x0400, "Specific access, bit 10", HFILL }},
18161
18162                 { &hf_access_specific_9,
18163                   { "Specific access, bit 9", "nt.access_mask.specific_9",
18164                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18165                     0x0200, "Specific access, bit 9", HFILL }},
18166
18167                 { &hf_access_specific_8,
18168                   { "Specific access, bit 8", "nt.access_mask.specific_8",
18169                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18170                     0x0100, "Specific access, bit 8", HFILL }},
18171
18172                 { &hf_access_specific_7,
18173                   { "Specific access, bit 7", "nt.access_mask.specific_7",
18174                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18175                     0x0080, "Specific access, bit 7", HFILL }},
18176
18177                 { &hf_access_specific_6,
18178                   { "Specific access, bit 6", "nt.access_mask.specific_6",
18179                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18180                     0x0040, "Specific access, bit 6", HFILL }},
18181
18182                 { &hf_access_specific_5,
18183                   { "Specific access, bit 5", "nt.access_mask.specific_5",
18184                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18185                     0x0020, "Specific access, bit 5", HFILL }},
18186
18187                 { &hf_access_specific_4,
18188                   { "Specific access, bit 4", "nt.access_mask.specific_4",
18189                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18190                     0x0010, "Specific access, bit 4", HFILL }},
18191
18192                 { &hf_access_specific_3,
18193                   { "Specific access, bit 3", "nt.access_mask.specific_3",
18194                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18195                     0x0008, "Specific access, bit 3", HFILL }},
18196
18197                 { &hf_access_specific_2,
18198                   { "Specific access, bit 2", "nt.access_mask.specific_2",
18199                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18200                     0x0004, "Specific access, bit 2", HFILL }},
18201
18202                 { &hf_access_specific_1,
18203                   { "Specific access, bit 1", "nt.access_mask.specific_1",
18204                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18205                     0x0002, "Specific access, bit 1", HFILL }},
18206
18207                 { &hf_access_specific_0,
18208                   { "Specific access, bit 0", "nt.access_mask.specific_0",
18209                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18210                     0x0001, "Specific access, bit 0", HFILL }},
18211         };
18212         static gint *ett[] = {
18213                 &ett_smb,
18214                 &ett_smb_hdr,
18215                 &ett_smb_command,
18216                 &ett_smb_fileattributes,
18217                 &ett_smb_capabilities,
18218                 &ett_smb_aflags,
18219                 &ett_smb_dialect,
18220                 &ett_smb_dialects,
18221                 &ett_smb_mode,
18222                 &ett_smb_rawmode,
18223                 &ett_smb_flags,
18224                 &ett_smb_flags2,
18225                 &ett_smb_desiredaccess,
18226                 &ett_smb_search,
18227                 &ett_smb_file,
18228                 &ett_smb_openfunction,
18229                 &ett_smb_filetype,
18230                 &ett_smb_openaction,
18231                 &ett_smb_writemode,
18232                 &ett_smb_lock_type,
18233                 &ett_smb_ssetupandxaction,
18234                 &ett_smb_optionsup,
18235                 &ett_smb_time_date,
18236                 &ett_smb_move_copy_flags,
18237                 &ett_smb_file_attributes,
18238                 &ett_smb_search_resume_key,
18239                 &ett_smb_search_dir_info,
18240                 &ett_smb_unlocks,
18241                 &ett_smb_unlock,
18242                 &ett_smb_locks,
18243                 &ett_smb_lock,
18244                 &ett_smb_open_flags,
18245                 &ett_smb_ipc_state,
18246                 &ett_smb_open_action,
18247                 &ett_smb_setup_action,
18248                 &ett_smb_connect_flags,
18249                 &ett_smb_connect_support_bits,
18250                 &ett_smb_nt_access_mask,
18251                 &ett_smb_nt_create_bits,
18252                 &ett_smb_nt_create_options,
18253                 &ett_smb_nt_share_access,
18254                 &ett_smb_nt_security_flags,
18255                 &ett_smb_nt_trans_setup,
18256                 &ett_smb_nt_trans_data,
18257                 &ett_smb_nt_trans_param,
18258                 &ett_smb_nt_notify_completion_filter,
18259                 &ett_smb_nt_ioctl_flags,
18260                 &ett_smb_security_information_mask,
18261                 &ett_smb_print_queue_entry,
18262                 &ett_smb_transaction_flags,
18263                 &ett_smb_transaction_params,
18264                 &ett_smb_find_first2_flags,
18265 #if 0
18266                 &ett_smb_ioflag,
18267 #endif
18268                 &ett_smb_transaction_data,
18269                 &ett_smb_stream_info,
18270                 &ett_smb_dfs_referrals,
18271                 &ett_smb_dfs_referral,
18272                 &ett_smb_dfs_referral_flags,
18273                 &ett_smb_get_dfs_flags,
18274                 &ett_smb_ff2_data,
18275                 &ett_smb_device_characteristics,
18276                 &ett_smb_fs_attributes,
18277                 &ett_smb_segments,
18278                 &ett_smb_segment,
18279                 &ett_smb_sec_desc,
18280                 &ett_smb_sid,
18281                 &ett_smb_acl,
18282                 &ett_smb_ace,
18283                 &ett_smb_ace_flags,
18284                 &ett_smb_sec_desc_type,
18285                 &ett_smb_quotaflags,
18286                 &ett_smb_secblob,
18287                 &ett_smb_mac_support_flags,
18288                 &ett_nt_access_mask,
18289                 &ett_nt_access_mask_generic,
18290                 &ett_nt_access_mask_standard,
18291                 &ett_nt_access_mask_specific,
18292         };
18293         module_t *smb_module;
18294
18295         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
18296             "SMB", "smb");
18297         proto_register_subtree_array(ett, array_length(ett));
18298         proto_register_field_array(proto_smb, hf, array_length(hf));
18299         register_init_routine(&smb_init_protocol);
18300         smb_module = prefs_register_protocol(proto_smb, NULL);
18301         prefs_register_bool_preference(smb_module, "trans_reassembly",
18302                 "Reassemble SMB Transaction payload",
18303                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
18304                 &smb_trans_reassembly);
18305         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
18306                 "Reassemble DCERPC over SMB",
18307                 "Whether the dissector should reassemble DCERPC over SMB commands",
18308                 &smb_dcerpc_reassembly);
18309         prefs_register_bool_preference(smb_module, "sid_name_snooping",
18310                 "Snoop SID to Name mappings",
18311                 "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
18312                 &sid_name_snooping);
18313
18314         register_init_routine(smb_trans_reassembly_init);
18315         smb_tap = register_tap("smb");
18316 }
18317
18318 void
18319 proto_reg_handoff_smb(void)
18320 {
18321         dissector_handle_t smb_handle;
18322
18323         gssapi_handle = find_dissector("gssapi");
18324         ntlmssp_handle = find_dissector("ntlmssp");
18325
18326         heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
18327         heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
18328         heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
18329         smb_handle = create_dissector_handle(dissect_smb, proto_smb);
18330         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
18331         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
18332         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER,
18333             smb_handle);
18334 }