Add new routines:
[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.353 2003/06/12 08:33:30 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_pid_high = -1;
104 static int hf_smb_sig = -1;
105 static int hf_smb_response_to = -1;
106 static int hf_smb_time = -1;
107 static int hf_smb_response_in = -1;
108 static int hf_smb_continuation_to = -1;
109 static int hf_smb_nt_status = -1;
110 static int hf_smb_error_class = -1;
111 static int hf_smb_error_code = -1;
112 static int hf_smb_reserved = -1;
113 static int hf_smb_flags_lock = -1;
114 static int hf_smb_flags_receive_buffer = -1;
115 static int hf_smb_flags_caseless = -1;
116 static int hf_smb_flags_canon = -1;
117 static int hf_smb_flags_oplock = -1;
118 static int hf_smb_flags_notify = -1;
119 static int hf_smb_flags_response = -1;
120 static int hf_smb_flags2_long_names_allowed = -1;
121 static int hf_smb_flags2_ea = -1;
122 static int hf_smb_flags2_sec_sig = -1;
123 static int hf_smb_flags2_long_names_used = -1;
124 static int hf_smb_flags2_esn = -1;
125 static int hf_smb_flags2_dfs = -1;
126 static int hf_smb_flags2_roe = -1;
127 static int hf_smb_flags2_nt_error = -1;
128 static int hf_smb_flags2_string = -1;
129 static int hf_smb_word_count = -1;
130 static int hf_smb_byte_count = -1;
131 static int hf_smb_buffer_format = -1;
132 static int hf_smb_dialect_name = -1;
133 static int hf_smb_dialect_index = -1;
134 static int hf_smb_max_trans_buf_size = -1;
135 static int hf_smb_max_mpx_count = -1;
136 static int hf_smb_max_vcs_num = -1;
137 static int hf_smb_session_key = -1;
138 static int hf_smb_server_timezone = -1;
139 static int hf_smb_encryption_key_length = -1;
140 static int hf_smb_encryption_key = -1;
141 static int hf_smb_primary_domain = -1;
142 static int hf_smb_server = -1;
143 static int hf_smb_max_raw_buf_size = -1;
144 static int hf_smb_server_guid = -1;
145 static int hf_smb_security_blob_len = -1;
146 static int hf_smb_security_blob = -1;
147 static int hf_smb_sm_mode16 = -1;
148 static int hf_smb_sm_password16 = -1;
149 static int hf_smb_sm_mode = -1;
150 static int hf_smb_sm_password = -1;
151 static int hf_smb_sm_signatures = -1;
152 static int hf_smb_sm_sig_required = -1;
153 static int hf_smb_rm_read = -1;
154 static int hf_smb_rm_write = -1;
155 static int hf_smb_server_date_time = -1;
156 static int hf_smb_server_smb_date = -1;
157 static int hf_smb_server_smb_time = -1;
158 static int hf_smb_server_cap_raw_mode = -1;
159 static int hf_smb_server_cap_mpx_mode = -1;
160 static int hf_smb_server_cap_unicode = -1;
161 static int hf_smb_server_cap_large_files = -1;
162 static int hf_smb_server_cap_nt_smbs = -1;
163 static int hf_smb_server_cap_rpc_remote_apis = -1;
164 static int hf_smb_server_cap_nt_status = -1;
165 static int hf_smb_server_cap_level_ii_oplocks = -1;
166 static int hf_smb_server_cap_lock_and_read = -1;
167 static int hf_smb_server_cap_nt_find = -1;
168 static int hf_smb_server_cap_dfs = -1;
169 static int hf_smb_server_cap_infolevel_passthru = -1;
170 static int hf_smb_server_cap_large_readx = -1;
171 static int hf_smb_server_cap_large_writex = -1;
172 static int hf_smb_server_cap_unix = -1;
173 static int hf_smb_server_cap_reserved = -1;
174 static int hf_smb_server_cap_bulk_transfer = -1;
175 static int hf_smb_server_cap_compressed_data = -1;
176 static int hf_smb_server_cap_extended_security = -1;
177 static int hf_smb_system_time = -1;
178 static int hf_smb_unknown = -1;
179 static int hf_smb_dir_name = -1;
180 static int hf_smb_echo_count = -1;
181 static int hf_smb_echo_data = -1;
182 static int hf_smb_echo_seq_num = -1;
183 static int hf_smb_max_buf_size = -1;
184 static int hf_smb_password = -1;
185 static int hf_smb_password_len = -1;
186 static int hf_smb_ansi_password = -1;
187 static int hf_smb_ansi_password_len = -1;
188 static int hf_smb_unicode_password = -1;
189 static int hf_smb_unicode_password_len = -1;
190 static int hf_smb_path = -1;
191 static int hf_smb_service = -1;
192 static int hf_smb_move_flags_file = -1;
193 static int hf_smb_move_flags_dir = -1;
194 static int hf_smb_move_flags_verify = -1;
195 static int hf_smb_files_moved = -1;
196 static int hf_smb_copy_flags_file = -1;
197 static int hf_smb_copy_flags_dir = -1;
198 static int hf_smb_copy_flags_dest_mode = -1;
199 static int hf_smb_copy_flags_source_mode = -1;
200 static int hf_smb_copy_flags_verify = -1;
201 static int hf_smb_copy_flags_tree_copy = -1;
202 static int hf_smb_copy_flags_ea_action = -1;
203 static int hf_smb_count = -1;
204 static int hf_smb_file_name = -1;
205 static int hf_smb_open_function_open = -1;
206 static int hf_smb_open_function_create = -1;
207 static int hf_smb_fid = -1;
208 static int hf_smb_file_attr_read_only_16bit = -1;
209 static int hf_smb_file_attr_read_only_8bit = -1;
210 static int hf_smb_file_attr_hidden_16bit = -1;
211 static int hf_smb_file_attr_hidden_8bit = -1;
212 static int hf_smb_file_attr_system_16bit = -1;
213 static int hf_smb_file_attr_system_8bit = -1;
214 static int hf_smb_file_attr_volume_16bit = -1;
215 static int hf_smb_file_attr_volume_8bit = -1;
216 static int hf_smb_file_attr_directory_16bit = -1;
217 static int hf_smb_file_attr_directory_8bit = -1;
218 static int hf_smb_file_attr_archive_16bit = -1;
219 static int hf_smb_file_attr_archive_8bit = -1;
220 static int hf_smb_file_attr_device = -1;
221 static int hf_smb_file_attr_normal = -1;
222 static int hf_smb_file_attr_temporary = -1;
223 static int hf_smb_file_attr_sparse = -1;
224 static int hf_smb_file_attr_reparse = -1;
225 static int hf_smb_file_attr_compressed = -1;
226 static int hf_smb_file_attr_offline = -1;
227 static int hf_smb_file_attr_not_content_indexed = -1;
228 static int hf_smb_file_attr_encrypted = -1;
229 static int hf_smb_file_size = -1;
230 static int hf_smb_search_attribute_read_only = -1;
231 static int hf_smb_search_attribute_hidden = -1;
232 static int hf_smb_search_attribute_system = -1;
233 static int hf_smb_search_attribute_volume = -1;
234 static int hf_smb_search_attribute_directory = -1;
235 static int hf_smb_search_attribute_archive = -1;
236 static int hf_smb_access_mode = -1;
237 static int hf_smb_access_sharing = -1;
238 static int hf_smb_access_locality = -1;
239 static int hf_smb_access_caching = -1;
240 static int hf_smb_access_writetru = -1;
241 static int hf_smb_create_time = -1;
242 static int hf_smb_modify_time = -1;
243 static int hf_smb_backup_time = -1;
244 static int hf_smb_mac_alloc_block_count = -1;
245 static int hf_smb_mac_alloc_block_size = -1;
246 static int hf_smb_mac_free_block_count = -1;
247 static int hf_smb_mac_fndrinfo = -1;
248 static int hf_smb_mac_root_file_count = -1;
249 static int hf_smb_mac_root_dir_count = -1;
250 static int hf_smb_mac_file_count = -1;
251 static int hf_smb_mac_dir_count = -1;
252 static int hf_smb_mac_support_flags = -1;
253 static int hf_smb_mac_sup_access_ctrl = -1;
254 static int hf_smb_mac_sup_getset_comments = -1;
255 static int hf_smb_mac_sup_desktopdb_calls = -1;
256 static int hf_smb_mac_sup_unique_ids = -1;
257 static int hf_smb_mac_sup_streams = -1;
258 static int hf_smb_create_dos_date = -1;
259 static int hf_smb_create_dos_time = -1;
260 static int hf_smb_last_write_time = -1;
261 static int hf_smb_last_write_dos_date = -1;
262 static int hf_smb_last_write_dos_time = -1;
263 static int hf_smb_access_time = -1;
264 static int hf_smb_access_dos_date = -1;
265 static int hf_smb_access_dos_time = -1;
266 static int hf_smb_old_file_name = -1;
267 static int hf_smb_offset = -1;
268 static int hf_smb_remaining = -1;
269 static int hf_smb_padding = -1;
270 static int hf_smb_file_data = -1;
271 static int hf_smb_total_data_len = -1;
272 static int hf_smb_data_len = -1;
273 static int hf_smb_seek_mode = -1;
274 static int hf_smb_data_size = -1;
275 static int hf_smb_alloc_size = -1;
276 static int hf_smb_alloc_size64 = -1;
277 static int hf_smb_max_count = -1;
278 static int hf_smb_min_count = -1;
279 static int hf_smb_timeout = -1;
280 static int hf_smb_high_offset = -1;
281 static int hf_smb_units = -1;
282 static int hf_smb_bpu = -1;
283 static int hf_smb_blocksize = -1;
284 static int hf_smb_freeunits = -1;
285 static int hf_smb_data_offset = -1;
286 static int hf_smb_dcm = -1;
287 static int hf_smb_request_mask = -1;
288 static int hf_smb_response_mask = -1;
289 static int hf_smb_search_id = -1;
290 static int hf_smb_write_mode_write_through = -1;
291 static int hf_smb_write_mode_return_remaining = -1;
292 static int hf_smb_write_mode_raw = -1;
293 static int hf_smb_write_mode_message_start = -1;
294 static int hf_smb_write_mode_connectionless = -1;
295 static int hf_smb_resume_key_len = -1;
296 static int hf_smb_resume_find_id = -1;
297 static int hf_smb_resume_server_cookie = -1;
298 static int hf_smb_resume_client_cookie = -1;
299 static int hf_smb_andxoffset = -1;
300 static int hf_smb_lock_type_large = -1;
301 static int hf_smb_lock_type_cancel = -1;
302 static int hf_smb_lock_type_change = -1;
303 static int hf_smb_lock_type_oplock = -1;
304 static int hf_smb_lock_type_shared = -1;
305 static int hf_smb_locking_ol = -1;
306 static int hf_smb_number_of_locks = -1;
307 static int hf_smb_number_of_unlocks = -1;
308 static int hf_smb_lock_long_offset = -1;
309 static int hf_smb_lock_long_length = -1;
310 static int hf_smb_file_type = -1;
311 static int hf_smb_ipc_state_nonblocking = -1;
312 static int hf_smb_ipc_state_endpoint = -1;
313 static int hf_smb_ipc_state_pipe_type = -1;
314 static int hf_smb_ipc_state_read_mode = -1;
315 static int hf_smb_ipc_state_icount = -1;
316 static int hf_smb_server_fid = -1;
317 static int hf_smb_open_flags_add_info = -1;
318 static int hf_smb_open_flags_ex_oplock = -1;
319 static int hf_smb_open_flags_batch_oplock = -1;
320 static int hf_smb_open_flags_ealen = -1;
321 static int hf_smb_open_action_open = -1;
322 static int hf_smb_open_action_lock = -1;
323 static int hf_smb_vc_num = -1;
324 static int hf_smb_account = -1;
325 static int hf_smb_os = -1;
326 static int hf_smb_lanman = -1;
327 static int hf_smb_setup_action_guest = -1;
328 static int hf_smb_fs = -1;
329 static int hf_smb_connect_flags_dtid = -1;
330 static int hf_smb_connect_support_search = -1;
331 static int hf_smb_connect_support_in_dfs = -1;
332 static int hf_smb_max_setup_count = -1;
333 static int hf_smb_total_param_count = -1;
334 static int hf_smb_total_data_count = -1;
335 static int hf_smb_max_param_count = -1;
336 static int hf_smb_max_data_count = -1;
337 static int hf_smb_param_disp16 = -1;
338 static int hf_smb_param_count16 = -1;
339 static int hf_smb_param_offset16 = -1;
340 static int hf_smb_param_disp32 = -1;
341 static int hf_smb_param_count32 = -1;
342 static int hf_smb_param_offset32 = -1;
343 static int hf_smb_data_disp16 = -1;
344 static int hf_smb_data_count16 = -1;
345 static int hf_smb_data_offset16 = -1;
346 static int hf_smb_data_disp32 = -1;
347 static int hf_smb_data_count32 = -1;
348 static int hf_smb_data_offset32 = -1;
349 static int hf_smb_setup_count = -1;
350 static int hf_smb_nt_trans_subcmd = -1;
351 static int hf_smb_nt_ioctl_function_code = -1;
352 static int hf_smb_nt_ioctl_isfsctl = -1;
353 static int hf_smb_nt_ioctl_flags_root_handle = -1;
354 static int hf_smb_nt_ioctl_data = -1;
355 #ifdef SMB_UNUSED_HANDLES
356 static int hf_smb_nt_security_information = -1;
357 #endif
358 static int hf_smb_nt_notify_action = -1;
359 static int hf_smb_nt_notify_watch_tree = -1;
360 static int hf_smb_nt_notify_stream_write = -1;
361 static int hf_smb_nt_notify_stream_size = -1;
362 static int hf_smb_nt_notify_stream_name = -1;
363 static int hf_smb_nt_notify_security = -1;
364 static int hf_smb_nt_notify_ea = -1;
365 static int hf_smb_nt_notify_creation = -1;
366 static int hf_smb_nt_notify_last_access = -1;
367 static int hf_smb_nt_notify_last_write = -1;
368 static int hf_smb_nt_notify_size = -1;
369 static int hf_smb_nt_notify_attributes = -1;
370 static int hf_smb_nt_notify_dir_name = -1;
371 static int hf_smb_nt_notify_file_name = -1;
372 static int hf_smb_root_dir_fid = -1;
373 static int hf_smb_nt_create_disposition = -1;
374 static int hf_smb_sd_length = -1;
375 static int hf_smb_ea_list_length = -1;
376 static int hf_smb_ea_flags = -1;
377 static int hf_smb_ea_name_length = -1;
378 static int hf_smb_ea_data_length = -1;
379 static int hf_smb_ea_name = -1;
380 static int hf_smb_ea_data = -1;
381 static int hf_smb_file_name_len = -1;
382 static int hf_smb_nt_impersonation_level = -1;
383 static int hf_smb_nt_security_flags_context_tracking = -1;
384 static int hf_smb_nt_security_flags_effective_only = -1;
385 static int hf_smb_nt_access_mask_generic_read = -1;
386 static int hf_smb_nt_access_mask_generic_write = -1;
387 static int hf_smb_nt_access_mask_generic_execute = -1;
388 static int hf_smb_nt_access_mask_generic_all = -1;
389 static int hf_smb_nt_access_mask_maximum_allowed = -1;
390 static int hf_smb_nt_access_mask_system_security = -1;
391 static int hf_smb_nt_access_mask_synchronize = -1;
392 static int hf_smb_nt_access_mask_write_owner = -1;
393 static int hf_smb_nt_access_mask_write_dac = -1;
394 static int hf_smb_nt_access_mask_read_control = -1;
395 static int hf_smb_nt_access_mask_delete = -1;
396 static int hf_smb_nt_access_mask_write_attributes = -1;
397 static int hf_smb_nt_access_mask_read_attributes = -1;
398 static int hf_smb_nt_access_mask_delete_child = -1;
399 static int hf_smb_nt_access_mask_execute = -1;
400 static int hf_smb_nt_access_mask_write_ea = -1;
401 static int hf_smb_nt_access_mask_read_ea = -1;
402 static int hf_smb_nt_access_mask_append = -1;
403 static int hf_smb_nt_access_mask_write = -1;
404 static int hf_smb_nt_access_mask_read = -1;
405 static int hf_smb_nt_create_bits_oplock = -1;
406 static int hf_smb_nt_create_bits_boplock = -1;
407 static int hf_smb_nt_create_bits_dir = -1;
408 static int hf_smb_nt_create_bits_ext_resp = -1;
409 static int hf_smb_nt_create_options_directory_file = -1;
410 static int hf_smb_nt_create_options_write_through = -1;
411 static int hf_smb_nt_create_options_sequential_only = -1;
412 static int hf_smb_nt_create_options_sync_io_alert = -1;
413 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
414 static int hf_smb_nt_create_options_non_directory_file = -1;
415 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
416 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
417 static int hf_smb_nt_create_options_random_access = -1;
418 static int hf_smb_nt_create_options_delete_on_close = -1;
419 static int hf_smb_nt_share_access_read = -1;
420 static int hf_smb_nt_share_access_write = -1;
421 static int hf_smb_nt_share_access_delete = -1;
422 static int hf_smb_file_eattr_read_only = -1;
423 static int hf_smb_file_eattr_hidden = -1;
424 static int hf_smb_file_eattr_system = -1;
425 static int hf_smb_file_eattr_volume = -1;
426 static int hf_smb_file_eattr_directory = -1;
427 static int hf_smb_file_eattr_archive = -1;
428 static int hf_smb_file_eattr_device = -1;
429 static int hf_smb_file_eattr_normal = -1;
430 static int hf_smb_file_eattr_temporary = -1;
431 static int hf_smb_file_eattr_sparse = -1;
432 static int hf_smb_file_eattr_reparse = -1;
433 static int hf_smb_file_eattr_compressed = -1;
434 static int hf_smb_file_eattr_offline = -1;
435 static int hf_smb_file_eattr_not_content_indexed = -1;
436 static int hf_smb_file_eattr_encrypted = -1;
437 static int hf_smb_sec_desc_len = -1;
438 static int hf_smb_sec_desc_revision = -1;
439 static int hf_smb_sec_desc_type_owner_defaulted = -1;
440 static int hf_smb_sec_desc_type_group_defaulted = -1;
441 static int hf_smb_sec_desc_type_dacl_present = -1;
442 static int hf_smb_sec_desc_type_dacl_defaulted = -1;
443 static int hf_smb_sec_desc_type_sacl_present = -1;
444 static int hf_smb_sec_desc_type_sacl_defaulted = -1;
445 static int hf_smb_sec_desc_type_dacl_auto_inherit_req = -1;
446 static int hf_smb_sec_desc_type_sacl_auto_inherit_req = -1;
447 static int hf_smb_sec_desc_type_dacl_auto_inherited = -1;
448 static int hf_smb_sec_desc_type_sacl_auto_inherited = -1;
449 static int hf_smb_sec_desc_type_dacl_protected = -1;
450 static int hf_smb_sec_desc_type_sacl_protected = -1;
451 static int hf_smb_sec_desc_type_self_relative = -1;
452 static int hf_smb_sid = -1;
453 static int hf_smb_sid_revision = -1;
454 static int hf_smb_sid_num_auth = -1;
455 static int hf_smb_acl_revision = -1;
456 static int hf_smb_acl_size = -1;
457 static int hf_smb_acl_num_aces = -1;
458 static int hf_smb_ace_type = -1;
459 static int hf_smb_ace_size = -1;
460 static int hf_smb_ace_flags_object_inherit = -1;
461 static int hf_smb_ace_flags_container_inherit = -1;
462 static int hf_smb_ace_flags_non_propagate_inherit = -1;
463 static int hf_smb_ace_flags_inherit_only = -1;
464 static int hf_smb_ace_flags_inherited_ace = -1;
465 static int hf_smb_ace_flags_successful_access = -1;
466 static int hf_smb_ace_flags_failed_access = -1;
467 static int hf_smb_nt_qsd_owner = -1;
468 static int hf_smb_nt_qsd_group = -1;
469 static int hf_smb_nt_qsd_dacl = -1;
470 static int hf_smb_nt_qsd_sacl = -1;
471 static int hf_smb_extended_attributes = -1;
472 static int hf_smb_oplock_level = -1;
473 static int hf_smb_create_action = -1;
474 static int hf_smb_file_id = -1;
475 static int hf_smb_ea_error_offset = -1;
476 static int hf_smb_end_of_file = -1;
477 static int hf_smb_device_type = -1;
478 static int hf_smb_is_directory = -1;
479 static int hf_smb_next_entry_offset = -1;
480 static int hf_smb_change_time = -1;
481 static int hf_smb_setup_len = -1;
482 static int hf_smb_print_mode = -1;
483 static int hf_smb_print_identifier = -1;
484 static int hf_smb_restart_index = -1;
485 static int hf_smb_print_queue_date = -1;
486 static int hf_smb_print_queue_dos_date = -1;
487 static int hf_smb_print_queue_dos_time = -1;
488 static int hf_smb_print_status = -1;
489 static int hf_smb_print_spool_file_number = -1;
490 static int hf_smb_print_spool_file_size = -1;
491 static int hf_smb_print_spool_file_name = -1;
492 static int hf_smb_start_index = -1;
493 static int hf_smb_originator_name = -1;
494 static int hf_smb_destination_name = -1;
495 static int hf_smb_message_len = -1;
496 static int hf_smb_message = -1;
497 static int hf_smb_mgid = -1;
498 static int hf_smb_forwarded_name = -1;
499 static int hf_smb_machine_name = -1;
500 static int hf_smb_cancel_to = -1;
501 static int hf_smb_trans2_subcmd = -1;
502 static int hf_smb_trans_name = -1;
503 static int hf_smb_transaction_flags_dtid = -1;
504 static int hf_smb_transaction_flags_owt = -1;
505 static int hf_smb_search_count = -1;
506 static int hf_smb_search_pattern = -1;
507 static int hf_smb_ff2_backup = -1;
508 static int hf_smb_ff2_continue = -1;
509 static int hf_smb_ff2_resume = -1;
510 static int hf_smb_ff2_close_eos = -1;
511 static int hf_smb_ff2_close = -1;
512 static int hf_smb_ff2_information_level = -1;
513 static int hf_smb_qpi_loi = -1;
514 static int hf_smb_spi_loi = -1;
515 #if 0
516 static int hf_smb_sfi_writetru = -1;
517 static int hf_smb_sfi_caching = -1;
518 #endif
519 static int hf_smb_storage_type = -1;
520 static int hf_smb_resume = -1;
521 static int hf_smb_max_referral_level = -1;
522 static int hf_smb_qfsi_information_level = -1;
523 static int hf_smb_number_of_links = -1;
524 static int hf_smb_delete_pending = -1;
525 static int hf_smb_index_number = -1;
526 static int hf_smb_current_offset = -1;
527 static int hf_smb_t2_alignment = -1;
528 static int hf_smb_t2_stream_name_length = -1;
529 static int hf_smb_t2_stream_size = -1;
530 static int hf_smb_t2_stream_name = -1;
531 static int hf_smb_t2_compressed_file_size = -1;
532 static int hf_smb_t2_compressed_format = -1;
533 static int hf_smb_t2_compressed_unit_shift = -1;
534 static int hf_smb_t2_compressed_chunk_shift = -1;
535 static int hf_smb_t2_compressed_cluster_shift = -1;
536 static int hf_smb_t2_marked_for_deletion = -1;
537 static int hf_smb_dfs_path_consumed = -1;
538 static int hf_smb_dfs_num_referrals = -1;
539 static int hf_smb_get_dfs_server_hold_storage = -1;
540 static int hf_smb_get_dfs_fielding = -1;
541 static int hf_smb_dfs_referral_version = -1;
542 static int hf_smb_dfs_referral_size = -1;
543 static int hf_smb_dfs_referral_server_type = -1;
544 static int hf_smb_dfs_referral_flags_strip = -1;
545 static int hf_smb_dfs_referral_node_offset = -1;
546 static int hf_smb_dfs_referral_node = -1;
547 static int hf_smb_dfs_referral_proximity = -1;
548 static int hf_smb_dfs_referral_ttl = -1;
549 static int hf_smb_dfs_referral_path_offset = -1;
550 static int hf_smb_dfs_referral_path = -1;
551 static int hf_smb_dfs_referral_alt_path_offset = -1;
552 static int hf_smb_dfs_referral_alt_path = -1;
553 static int hf_smb_end_of_search = -1;
554 static int hf_smb_last_name_offset = -1;
555 static int hf_smb_fn_information_level = -1;
556 static int hf_smb_monitor_handle = -1;
557 static int hf_smb_change_count = -1;
558 static int hf_smb_file_index = -1;
559 static int hf_smb_short_file_name = -1;
560 static int hf_smb_short_file_name_len = -1;
561 static int hf_smb_fs_id = -1;
562 static int hf_smb_sector_unit = -1;
563 static int hf_smb_fs_units = -1;
564 static int hf_smb_fs_sector = -1;
565 static int hf_smb_avail_units = -1;
566 static int hf_smb_volume_serial_num = -1;
567 static int hf_smb_volume_label_len = -1;
568 static int hf_smb_volume_label = -1;
569 static int hf_smb_free_alloc_units64 = -1;
570 static int hf_smb_caller_free_alloc_units64 = -1;
571 static int hf_smb_actual_free_alloc_units64 = -1;
572 static int hf_smb_max_name_len = -1;
573 static int hf_smb_fs_name_len = -1;
574 static int hf_smb_fs_name = -1;
575 static int hf_smb_device_char_removable = -1;
576 static int hf_smb_device_char_read_only = -1;
577 static int hf_smb_device_char_floppy = -1;
578 static int hf_smb_device_char_write_once = -1;
579 static int hf_smb_device_char_remote = -1;
580 static int hf_smb_device_char_mounted = -1;
581 static int hf_smb_device_char_virtual = -1;
582 static int hf_smb_fs_attr_css = -1;
583 static int hf_smb_fs_attr_cpn = -1;
584 static int hf_smb_fs_attr_pacls = -1;
585 static int hf_smb_fs_attr_fc = -1;
586 static int hf_smb_fs_attr_vq = -1;
587 static int hf_smb_fs_attr_dim = -1;
588 static int hf_smb_fs_attr_vic = -1;
589 static int hf_smb_quota_flags_enabled = -1;
590 static int hf_smb_quota_flags_deny_disk = -1;
591 static int hf_smb_quota_flags_log_limit = -1;
592 static int hf_smb_quota_flags_log_warning = -1;
593 static int hf_smb_soft_quota_limit = -1;
594 static int hf_smb_hard_quota_limit = -1;
595 static int hf_smb_user_quota_used = -1;
596 static int hf_smb_user_quota_offset = -1;
597 static int hf_smb_nt_rename_level = -1;
598 static int hf_smb_cluster_count = -1;
599 static int hf_smb_segments = -1;
600 static int hf_smb_segment = -1;
601 static int hf_smb_segment_overlap = -1;
602 static int hf_smb_segment_overlap_conflict = -1;
603 static int hf_smb_segment_multiple_tails = -1;
604 static int hf_smb_segment_too_long_fragment = -1;
605 static int hf_smb_segment_error = -1;
606 static int hf_smb_pipe_write_len = -1;
607
608 static gint ett_smb = -1;
609 static gint ett_smb_hdr = -1;
610 static gint ett_smb_command = -1;
611 static gint ett_smb_fileattributes = -1;
612 static gint ett_smb_capabilities = -1;
613 static gint ett_smb_aflags = -1;
614 static gint ett_smb_dialect = -1;
615 static gint ett_smb_dialects = -1;
616 static gint ett_smb_mode = -1;
617 static gint ett_smb_rawmode = -1;
618 static gint ett_smb_flags = -1;
619 static gint ett_smb_flags2 = -1;
620 static gint ett_smb_desiredaccess = -1;
621 static gint ett_smb_search = -1;
622 static gint ett_smb_file = -1;
623 static gint ett_smb_openfunction = -1;
624 static gint ett_smb_filetype = -1;
625 static gint ett_smb_openaction = -1;
626 static gint ett_smb_writemode = -1;
627 static gint ett_smb_lock_type = -1;
628 static gint ett_smb_ssetupandxaction = -1;
629 static gint ett_smb_optionsup = -1;
630 static gint ett_smb_time_date = -1;
631 static gint ett_smb_move_copy_flags = -1;
632 static gint ett_smb_file_attributes = -1;
633 static gint ett_smb_search_resume_key = -1;
634 static gint ett_smb_search_dir_info = -1;
635 static gint ett_smb_unlocks = -1;
636 static gint ett_smb_unlock = -1;
637 static gint ett_smb_locks = -1;
638 static gint ett_smb_lock = -1;
639 static gint ett_smb_open_flags = -1;
640 static gint ett_smb_ipc_state = -1;
641 static gint ett_smb_open_action = -1;
642 static gint ett_smb_setup_action = -1;
643 static gint ett_smb_connect_flags = -1;
644 static gint ett_smb_connect_support_bits = -1;
645 static gint ett_smb_nt_access_mask = -1;
646 static gint ett_smb_nt_create_bits = -1;
647 static gint ett_smb_nt_create_options = -1;
648 static gint ett_smb_nt_share_access = -1;
649 static gint ett_smb_nt_security_flags = -1;
650 static gint ett_smb_nt_trans_setup = -1;
651 static gint ett_smb_nt_trans_data = -1;
652 static gint ett_smb_nt_trans_param = -1;
653 static gint ett_smb_nt_notify_completion_filter = -1;
654 static gint ett_smb_nt_ioctl_flags = -1;
655 static gint ett_smb_security_information_mask = -1;
656 static gint ett_smb_print_queue_entry = -1;
657 static gint ett_smb_transaction_flags = -1;
658 static gint ett_smb_transaction_params = -1;
659 static gint ett_smb_find_first2_flags = -1;
660 static gint ett_smb_mac_support_flags = -1;
661 #if 0
662 static gint ett_smb_ioflag = -1;
663 #endif
664 static gint ett_smb_transaction_data = -1;
665 static gint ett_smb_stream_info = -1;
666 static gint ett_smb_dfs_referrals = -1;
667 static gint ett_smb_dfs_referral = -1;
668 static gint ett_smb_dfs_referral_flags = -1;
669 static gint ett_smb_get_dfs_flags = -1;
670 static gint ett_smb_ff2_data = -1;
671 static gint ett_smb_device_characteristics = -1;
672 static gint ett_smb_fs_attributes = -1;
673 static gint ett_smb_segments = -1;
674 static gint ett_smb_segment = -1;
675 static gint ett_smb_sec_desc = -1;
676 static gint ett_smb_sid = -1;
677 static gint ett_smb_acl = -1;
678 static gint ett_smb_ace = -1;
679 static gint ett_smb_ace_flags = -1;
680 static gint ett_smb_sec_desc_type = -1;
681 static gint ett_smb_quotaflags = -1;
682 static gint ett_smb_secblob = -1;
683 static gint ett_smb_unicode_password = -1;
684 static gint ett_smb_ea = -1;
685
686 static int smb_tap = -1;
687
688 static dissector_handle_t gssapi_handle = NULL;
689 static dissector_handle_t ntlmssp_handle = NULL;
690
691 static const fragment_items smb_frag_items = {
692         &ett_smb_segment,
693         &ett_smb_segments,
694
695         &hf_smb_segments,
696         &hf_smb_segment,
697         &hf_smb_segment_overlap,
698         &hf_smb_segment_overlap_conflict,
699         &hf_smb_segment_multiple_tails,
700         &hf_smb_segment_too_long_fragment,
701         &hf_smb_segment_error,
702         NULL,
703
704         "segments"
705 };
706
707 proto_tree *top_tree=NULL;     /* ugly */
708
709 static char *decode_smb_name(unsigned char);
710 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu);
711
712 /*
713  * Macros for use in the main dissector routines for an SMB.
714  */
715
716 #define WORD_COUNT      \
717         /* Word Count */                                \
718         wc = tvb_get_guint8(tvb, offset);               \
719         proto_tree_add_uint(tree, hf_smb_word_count,    \
720                 tvb, offset, 1, wc);                    \
721         offset += 1;                                    \
722         if(wc==0) goto bytecount;
723
724 #define BYTE_COUNT      \
725         bytecount:                                      \
726         bc = tvb_get_letohs(tvb, offset);               \
727         proto_tree_add_uint(tree, hf_smb_byte_count,    \
728                         tvb, offset, 2, bc);            \
729         offset += 2;                                    \
730         if(bc==0) goto endofcommand;
731
732 #define CHECK_BYTE_COUNT(len)   \
733         if (bc < len) goto endofcommand;
734
735 #define COUNT_BYTES(len)   {\
736         int tmp;            \
737         tmp=len;            \
738         offset += tmp;      \
739         bc -= tmp;          \
740         }
741
742 #define END_OF_SMB      \
743         if (bc != 0) { \
744                 proto_tree_add_text(tree, tvb, offset, bc, \
745                     "Extra byte parameters");           \
746                 offset += bc;                           \
747         }                                               \
748         endofcommand:
749
750 /*
751  * Macros for use in routines called by them.
752  */
753 #define CHECK_BYTE_COUNT_SUBR(len)      \
754         if (*bcp < len) {               \
755                 *trunc = TRUE;          \
756                 return offset;          \
757         }
758
759 #define CHECK_STRING_SUBR(fn)   \
760         if (fn == NULL) {       \
761                 *trunc = TRUE;  \
762                 return offset;  \
763         }
764
765 #define COUNT_BYTES_SUBR(len)   \
766         offset += len;          \
767         *bcp -= len;
768
769 /*
770  * Macros for use when dissecting transaction parameters and data
771  */
772 #define CHECK_BYTE_COUNT_TRANS(len)     \
773         if (bc < len) return offset;
774
775 #define CHECK_STRING_TRANS(fn)  \
776         if (fn == NULL) return offset;
777
778 #define COUNT_BYTES_TRANS(len)  \
779         offset += len;          \
780         bc -= len;
781
782 /*
783  * Macros for use in subrroutines dissecting transaction parameters or data
784  */
785 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
786         if (*bcp < len) return offset;
787
788 #define CHECK_STRING_TRANS_SUBR(fn)     \
789         if (fn == NULL) return offset;
790
791 #define COUNT_BYTES_TRANS_SUBR(len)     \
792         offset += len;                  \
793         *bcp -= len;
794
795
796 gboolean sid_name_snooping = FALSE;
797
798 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
799    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
800    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
801 static gboolean smb_trans_reassembly = FALSE;
802 gboolean smb_dcerpc_reassembly = FALSE;
803
804 static GHashTable *smb_trans_fragment_table = NULL;
805
806 static void
807 smb_trans_reassembly_init(void)
808 {
809         fragment_table_init(&smb_trans_fragment_table);
810 }
811
812 static fragment_data *
813 smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
814                      int offset, int count, int pos, int totlen)
815 {
816         fragment_data *fd_head=NULL;
817         smb_info_t *si;
818         int more_frags;
819
820         more_frags=totlen>(pos+count);
821
822         si = (smb_info_t *)pinfo->private_data;
823         if (si->sip == NULL) {
824                 /*
825                  * We don't have the frame number of the request.
826                  *
827                  * XXX - is there truly nothing we can do here?
828                  * Can we not separately keep track of the original
829                  * transaction and its continuations, as we did
830                  * at one time?
831                  *
832                  * It is probably not much point in even trying to do something here
833                  * if we have never seen the initial request. Without the initial
834                  * request we probably miss all parameters and the begining of data
835                  * so we cant even call a subdissector since we can not determine
836                  * which type of transaction call this is.
837                  */
838                 return NULL;
839         }
840
841         if(!pinfo->fd->flags.visited){
842                 fd_head = fragment_add(tvb, offset, pinfo,
843                                        si->sip->frame_req, smb_trans_fragment_table,
844                                        pos, count, more_frags);
845         } else {
846                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
847         }
848
849         /* we only show the defragmented packet for the first fragment,
850            or else we might end up with dissecting one HUGE transaction PDU
851            a LOT of times. (first fragment is the only one containing the setup
852            bytes)
853            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction
854            SMBs. Takes a LOT of time dissecting and is not fun.
855         */
856         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
857                 return fd_head;
858         } else {
859                 return NULL;
860         }
861 }
862
863
864
865
866
867 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
868    These variables and functions are used to match
869    responses with calls
870    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
871 /*
872  * The information we need to save about a request in order to show the
873  * frame number of the request in the dissection of the reply.
874  */
875 typedef struct  {
876         guint32 frame;
877         guint32 pid_mid;
878 } smb_saved_info_key_t;
879
880 static GMemChunk *smb_saved_info_key_chunk = NULL;
881 static GMemChunk *smb_saved_info_chunk = NULL;
882 static int smb_saved_info_init_count = 200;
883
884 /* unmatched smb_saved_info structures.
885    For unmatched smb_saved_info structures we store the smb_saved_info
886    structure using the MID and the PID as the key.
887
888    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
889    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
890    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
891 */
892 static gint
893 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
894 {
895         register guint32 key1 = (guint32)k1;
896         register guint32 key2 = (guint32)k2;
897         return key1==key2;
898 }
899 static guint
900 smb_saved_info_hash_unmatched(gconstpointer k)
901 {
902         register guint32 key = (guint32)k;
903         return key;
904 }
905
906 /* matched smb_saved_info structures.
907    For matched smb_saved_info structures we store the smb_saved_info
908    structure twice in the table using the frame number, and a combination
909    of the MID and the PID, as the key.
910    The frame number is guaranteed to be unique but if ever someone makes
911    some change that will renumber the frames in a capture we are in BIG trouble.
912    This is not likely though since that would break (among other things) all the
913    reassembly routines as well.
914
915    We also need the MID as there may be more than one SMB request or reply
916    in a single frame, and we also need the PID as there may be more than
917    one outstanding request with the same MID and different PIDs.
918 */
919 static gint
920 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
921 {
922         const smb_saved_info_key_t *key1 = k1;
923         const smb_saved_info_key_t *key2 = k2;
924         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
925 }
926 static guint
927 smb_saved_info_hash_matched(gconstpointer k)
928 {
929         const smb_saved_info_key_t *key = k;
930         return key->frame + key->pid_mid;
931 }
932
933 static GMemChunk *smb_nt_transact_info_chunk = NULL;
934 static int smb_nt_transact_info_init_count = 200;
935
936 static GMemChunk *smb_transact2_info_chunk = NULL;
937 static int smb_transact2_info_init_count = 200;
938
939 /*
940  * The information we need to save about a Transaction request in order
941  * to dissect the reply; this includes information for use by the
942  * Remote API dissector.
943  */
944 static GMemChunk *smb_transact_info_chunk = NULL;
945 static int smb_transact_info_init_count = 200;
946
947 static GMemChunk *conv_tables_chunk = NULL;
948 static GSList *conv_tables = NULL;
949 static int conv_tables_count = 10;
950
951
952 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
953    End of request/response matching functions
954    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
955
956 static const value_string buffer_format_vals[] = {
957         {1,     "Data Block"},
958         {2,     "Dialect"},
959         {3,     "Pathname"},
960         {4,     "ASCII"},
961         {5,     "Variable Block"},
962         {0,     NULL}
963 };
964
965 /*
966  * UTIME - this is *almost* like a UNIX time stamp, except that it's
967  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
968  * January 1, 1970, 00:00:00 GMT.
969  *
970  * This means we have to do some extra work to convert it.  This code is
971  * based on the Samba code:
972  *
973  *      Unix SMB/Netbios implementation.
974  *      Version 1.9.
975  *      time handling functions
976  *      Copyright (C) Andrew Tridgell 1992-1998
977  */
978
979 /*
980  * Yield the difference between *A and *B, in seconds, ignoring leap
981  * seconds.
982  */
983 #define TM_YEAR_BASE 1900
984
985 static int
986 tm_diff(struct tm *a, struct tm *b)
987 {
988         int ay = a->tm_year + (TM_YEAR_BASE - 1);
989         int by = b->tm_year + (TM_YEAR_BASE - 1);
990         int intervening_leap_days =
991             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
992         int years = ay - by;
993         int days =
994             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
995         int hours = 24*days + (a->tm_hour - b->tm_hour);
996         int minutes = 60*hours + (a->tm_min - b->tm_min);
997         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
998
999         return seconds;
1000 }
1001
1002 /*
1003  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
1004  * determined.
1005  */
1006 static int
1007 TimeZone(time_t t)
1008 {
1009         struct tm *tm = gmtime(&t);
1010         struct tm tm_utc;
1011
1012         if (tm == NULL)
1013                 return 0;
1014         tm_utc = *tm;
1015         tm = localtime(&t);
1016         if (tm == NULL)
1017                 return 0;
1018         return tm_diff(&tm_utc,tm);
1019 }
1020
1021 /*
1022  * Return the same value as TimeZone, but it should be more efficient.
1023  *
1024  * We keep a table of DST offsets to prevent calling localtime() on each
1025  * call of this function. This saves a LOT of time on many unixes.
1026  *
1027  * Updated by Paul Eggert <eggert@twinsun.com>
1028  */
1029 #ifndef CHAR_BIT
1030 #define CHAR_BIT 8
1031 #endif
1032
1033 #ifndef TIME_T_MIN
1034 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1035                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
1036 #endif
1037 #ifndef TIME_T_MAX
1038 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
1039 #endif
1040
1041 static int
1042 TimeZoneFaster(time_t t)
1043 {
1044         static struct dst_table {time_t start,end; int zone;} *tdt;
1045         static struct dst_table *dst_table = NULL;
1046         static int table_size = 0;
1047         int i;
1048         int zone = 0;
1049
1050         if (t == 0)
1051                 t = time(NULL);
1052
1053         /* Tunis has a 8 day DST region, we need to be careful ... */
1054 #define MAX_DST_WIDTH (365*24*60*60)
1055 #define MAX_DST_SKIP (7*24*60*60)
1056
1057         for (i = 0; i < table_size; i++) {
1058                 if (t >= dst_table[i].start && t <= dst_table[i].end)
1059                         break;
1060         }
1061
1062         if (i < table_size) {
1063                 zone = dst_table[i].zone;
1064         } else {
1065                 time_t low,high;
1066
1067                 zone = TimeZone(t);
1068                 if (dst_table == NULL)
1069                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1070                 else
1071                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1072                 if (tdt == NULL) {
1073                         if (dst_table)
1074                                 g_free(dst_table);
1075                         table_size = 0;
1076                 } else {
1077                         dst_table = tdt;
1078                         table_size++;
1079
1080                         dst_table[i].zone = zone;
1081                         dst_table[i].start = dst_table[i].end = t;
1082
1083                         /* no entry will cover more than 6 months */
1084                         low = t - MAX_DST_WIDTH/2;
1085                         if (t < low)
1086                                 low = TIME_T_MIN;
1087
1088                         high = t + MAX_DST_WIDTH/2;
1089                         if (high < t)
1090                                 high = TIME_T_MAX;
1091
1092                         /*
1093                          * Widen the new entry using two bisection searches.
1094                          */
1095                         while (low+60*60 < dst_table[i].start) {
1096                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1097                                         t = dst_table[i].start - MAX_DST_SKIP;
1098                                 else
1099                                         t = low + (dst_table[i].start-low)/2;
1100                                 if (TimeZone(t) == zone)
1101                                         dst_table[i].start = t;
1102                                 else
1103                                         low = t;
1104                         }
1105
1106                         while (high-60*60 > dst_table[i].end) {
1107                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1108                                         t = dst_table[i].end + MAX_DST_SKIP;
1109                                 else
1110                                         t = high - (high-dst_table[i].end)/2;
1111                                 if (TimeZone(t) == zone)
1112                                         dst_table[i].end = t;
1113                                 else
1114                                         high = t;
1115                         }
1116                 }
1117         }
1118         return zone;
1119 }
1120
1121 /*
1122  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1123  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1124  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1125  * daylight savings transitions because some local times are ambiguous.
1126  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1127  */
1128 static int
1129 LocTimeDiff(time_t lt)
1130 {
1131         int d = TimeZoneFaster(lt);
1132         time_t t = lt + d;
1133
1134         /* if overflow occurred, ignore all the adjustments so far */
1135         if (((t < lt) ^ (d < 0)))
1136                 t = lt;
1137
1138         /*
1139          * Now t should be close enough to the true UTC to yield the
1140          * right answer.
1141          */
1142         return TimeZoneFaster(t);
1143 }
1144
1145 static int
1146 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1147 {
1148         guint32 timeval;
1149         nstime_t ts;
1150
1151         timeval = tvb_get_letohl(tvb, offset);
1152         if (timeval == 0xffffffff) {
1153                 proto_tree_add_text(tree, tvb, offset, 4,
1154                     "%s: No time specified (0xffffffff)",
1155                     proto_registrar_get_name(hf_date));
1156                 offset += 4;
1157                 return offset;
1158         }
1159
1160         /*
1161          * We add the local time offset.
1162          */
1163         ts.secs = timeval + LocTimeDiff(timeval);
1164         ts.nsecs = 0;
1165
1166         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1167         offset += 4;
1168
1169         return offset;
1170 }
1171
1172 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
1173
1174 /*
1175  * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits,
1176  * to an "nstime_t".
1177  * A FILETIME is a 64-bit integer, giving the time since Jan 1, 1601,
1178  * midnight "UTC", in 100ns units.
1179  * Return TRUE if the conversion succeeds, FALSE otherwise.
1180  *
1181  * According to the Samba code, it appears to be kludge-GMT (at least for
1182  * file listings). This means it's the GMT you get by taking a local time
1183  * and adding the server time zone offset.  This is NOT the same as GMT in
1184  * some cases.   However, we don't know the server time zone, so we don't
1185  * do that adjustment.
1186  *
1187  * This code is based on the Samba code:
1188  *
1189  *      Unix SMB/Netbios implementation.
1190  *      Version 1.9.
1191  *      time handling functions
1192  *      Copyright (C) Andrew Tridgell 1992-1998
1193  */
1194 static gboolean
1195 nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
1196 {
1197         double d;
1198         /* The next two lines are a fix needed for the
1199             broken SCO compiler. JRA. */
1200         time_t l_time_min = TIME_T_MIN;
1201         time_t l_time_max = TIME_T_MAX;
1202
1203         if (filetime_high == 0)
1204                 return FALSE;
1205
1206         /*
1207          * Get the time as a double, in seconds and fractional seconds.
1208          */
1209         d = ((double)filetime_high)*4.0*(double)(1<<30);
1210         d += filetime_low;
1211         d *= 1.0e-7;
1212
1213         /* Now adjust by 369 years, to make the seconds since 1970. */
1214         d -= TIME_FIXUP_CONSTANT;
1215
1216         if (!(l_time_min <= d && d <= l_time_max))
1217                 return FALSE;
1218
1219         /*
1220          * Get the time as seconds and nanoseconds.
1221          */
1222         tv->secs = d;
1223         tv->nsecs = (d - tv->secs)*1000000000;
1224
1225         return TRUE;
1226 }
1227
1228 int
1229 dissect_smb_64bit_time(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1230 {
1231         guint32 filetime_high, filetime_low;
1232         nstime_t ts;
1233
1234         /* XXX there seems also to be another special time value which is fairly common :
1235            0x40000000 00000000
1236            the meaning of this one is yet unknown
1237         */
1238         if (tree) {
1239                 filetime_low = tvb_get_letohl(tvb, offset);
1240                 filetime_high = tvb_get_letohl(tvb, offset + 4);
1241                 if (filetime_low == 0 && filetime_high == 0) {
1242                         proto_tree_add_text(tree, tvb, offset, 8,
1243                             "%s: No time specified (0)",
1244                             proto_registrar_get_name(hf_date));
1245                 } else if(filetime_low==0 && filetime_high==0x80000000){
1246                         proto_tree_add_text(tree, tvb, offset, 8,
1247                             "%s: Infinity (relative time)",
1248                             proto_registrar_get_name(hf_date));
1249                 } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
1250                         proto_tree_add_text(tree, tvb, offset, 8,
1251                             "%s: Infinity (absolute time)",
1252                             proto_registrar_get_name(hf_date));
1253                 } else {
1254                         if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
1255                                 proto_tree_add_time(tree, hf_date, tvb,
1256                                     offset, 8, &ts);
1257                         } else {
1258                                 proto_tree_add_text(tree, tvb, offset, 8,
1259                                     "%s: Time can't be converted",
1260                                     proto_registrar_get_name(hf_date));
1261                         }
1262                 }
1263         }
1264
1265         offset += 8;
1266         return offset;
1267 }
1268
1269 static int
1270 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1271     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1272 {
1273         guint16 dos_time, dos_date;
1274         proto_item *item = NULL;
1275         proto_tree *tree = NULL;
1276         struct tm tm;
1277         time_t t;
1278         static const int mday_noleap[12] = {
1279                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1280         };
1281         static const int mday_leap[12] = {
1282                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1283         };
1284 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1285         nstime_t tv;
1286
1287         if (time_first) {
1288                 dos_time = tvb_get_letohs(tvb, offset);
1289                 dos_date = tvb_get_letohs(tvb, offset+2);
1290         } else {
1291                 dos_date = tvb_get_letohs(tvb, offset);
1292                 dos_time = tvb_get_letohs(tvb, offset+2);
1293         }
1294
1295         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1296             (dos_date == 0 && dos_time == 0)) {
1297                 /*
1298                  * No date/time specified.
1299                  */
1300                 if(parent_tree){
1301                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1302                             "%s: No time specified (0x%08x)",
1303                             proto_registrar_get_name(hf_date),
1304                             (dos_date << 16) | dos_time);
1305                 }
1306                 offset += 4;
1307                 return offset;
1308         }
1309
1310         tm.tm_sec = (dos_time&0x1f)*2;
1311         tm.tm_min = (dos_time>>5)&0x3f;
1312         tm.tm_hour = (dos_time>>11)&0x1f;
1313         tm.tm_mday = dos_date&0x1f;
1314         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1315         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1316         tm.tm_isdst = -1;
1317
1318         /*
1319          * Do some sanity checks before calling "mktime()";
1320          * "mktime()" doesn't do them, it "normalizes" out-of-range
1321          * values.
1322          */
1323         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1324            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1325            (ISLEAP(tm.tm_year + 1900) ?
1326              tm.tm_mday > mday_leap[tm.tm_mon] :
1327              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1328              (t = mktime(&tm)) == -1) {
1329                 /*
1330                  * Invalid date/time.
1331                  */
1332                 if (parent_tree) {
1333                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1334                             "%s: Invalid time",
1335                             proto_registrar_get_name(hf_date));
1336                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1337                         if (time_first) {
1338                                 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);
1339                                 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);
1340                         } else {
1341                                 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);
1342                                 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);
1343                         }
1344                 }
1345                 offset += 4;
1346                 return offset;
1347         }
1348
1349         tv.secs = t;
1350         tv.nsecs = 0;
1351
1352         if(parent_tree){
1353                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1354                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1355                 if (time_first) {
1356                         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);
1357                         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);
1358                 } else {
1359                         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);
1360                         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);
1361                 }
1362         }
1363
1364         offset += 4;
1365
1366         return offset;
1367 }
1368
1369
1370 static const value_string da_access_vals[] = {
1371         { 0,            "Open for reading"},
1372         { 1,            "Open for writing"},
1373         { 2,            "Open for reading and writing"},
1374         { 3,            "Open for execute"},
1375         {0, NULL}
1376 };
1377 static const value_string da_sharing_vals[] = {
1378         { 0,            "Compatibility mode"},
1379         { 1,            "Deny read/write/execute (exclusive)"},
1380         { 2,            "Deny write"},
1381         { 3,            "Deny read/execute"},
1382         { 4,            "Deny none"},
1383         {0, NULL}
1384 };
1385 static const value_string da_locality_vals[] = {
1386         { 0,            "Locality of reference unknown"},
1387         { 1,            "Mainly sequential access"},
1388         { 2,            "Mainly random access"},
1389         { 3,            "Random access with some locality"},
1390         {0, NULL}
1391 };
1392 static const true_false_string tfs_da_caching = {
1393         "Do not cache this file",
1394         "Caching permitted on this file"
1395 };
1396 static const true_false_string tfs_da_writetru = {
1397         "Write through enabled",
1398         "Write through disabled"
1399 };
1400 static int
1401 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, char *type)
1402 {
1403         guint16 mask;
1404         proto_item *item = NULL;
1405         proto_tree *tree = NULL;
1406
1407         mask = tvb_get_letohs(tvb, offset);
1408
1409         if(parent_tree){
1410                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1411                         "%s Access: 0x%04x", type, mask);
1412                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1413         }
1414
1415         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1416                 tvb, offset, 2, mask);
1417         proto_tree_add_boolean(tree, hf_smb_access_caching,
1418                 tvb, offset, 2, mask);
1419         proto_tree_add_uint(tree, hf_smb_access_locality,
1420                 tvb, offset, 2, mask);
1421         proto_tree_add_uint(tree, hf_smb_access_sharing,
1422                 tvb, offset, 2, mask);
1423         proto_tree_add_uint(tree, hf_smb_access_mode,
1424                 tvb, offset, 2, mask);
1425
1426         offset += 2;
1427
1428         return offset;
1429 }
1430
1431 #define SMB_FILE_ATTRIBUTE_READ_ONLY            0x00000001
1432 #define SMB_FILE_ATTRIBUTE_HIDDEN                       0x00000002
1433 #define SMB_FILE_ATTRIBUTE_SYSTEM                       0x00000004
1434 #define SMB_FILE_ATTRIBUTE_VOLUME                       0x00000008
1435 #define SMB_FILE_ATTRIBUTE_DIRECTORY            0x00000010
1436 #define SMB_FILE_ATTRIBUTE_ARCHIVE                      0x00000020
1437 #define SMB_FILE_ATTRIBUTE_DEVICE                       0x00000040
1438 #define SMB_FILE_ATTRIBUTE_NORMAL                       0x00000080
1439 #define SMB_FILE_ATTRIBUTE_TEMPORARY            0x00000100
1440 #define SMB_FILE_ATTRIBUTE_SPARSE                       0x00000200
1441 #define SMB_FILE_ATTRIBUTE_REPARSE                      0x00000400
1442 #define SMB_FILE_ATTRIBUTE_COMPRESSED           0x00000800
1443 #define SMB_FILE_ATTRIBUTE_OFFLINE                      0x00001000
1444 #define SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
1445 #define SMB_FILE_ATTRIBUTE_ENCRYPTED            0x00004000
1446
1447 static const true_false_string tfs_file_attribute_read_only = {
1448         "This file is READ ONLY",
1449         "This file is NOT read only",
1450 };
1451 static const true_false_string tfs_file_attribute_hidden = {
1452         "This is a HIDDEN file",
1453         "This is NOT a hidden file"
1454 };
1455 static const true_false_string tfs_file_attribute_system = {
1456         "This is a SYSTEM file",
1457         "This is NOT a system file"
1458 };
1459 static const true_false_string tfs_file_attribute_volume = {
1460         "This is a VOLUME ID",
1461         "This is NOT a volume ID"
1462 };
1463 static const true_false_string tfs_file_attribute_directory = {
1464         "This is a DIRECTORY",
1465         "This is NOT a directory"
1466 };
1467 static const true_false_string tfs_file_attribute_archive = {
1468         "This file has been modified since last ARCHIVE",
1469         "This file has NOT been modified since last archive"
1470 };
1471 static const true_false_string tfs_file_attribute_device = {
1472         "This is a DEVICE",
1473         "This is NOT a device"
1474 };
1475 static const true_false_string tfs_file_attribute_normal = {
1476         "This file is an ordinary file",
1477         "This file has some attribute set"
1478 };
1479 static const true_false_string tfs_file_attribute_temporary = {
1480         "This is a TEMPORARY file",
1481         "This is NOT a temporary file"
1482 };
1483 static const true_false_string tfs_file_attribute_sparse = {
1484         "This is a SPARSE file",
1485         "This is NOT a sparse file"
1486 };
1487 static const true_false_string tfs_file_attribute_reparse = {
1488         "This file has an associated REPARSE POINT",
1489         "This file does NOT have an associated reparse point"
1490 };
1491 static const true_false_string tfs_file_attribute_compressed = {
1492         "This is a COMPRESSED file",
1493         "This is NOT a compressed file"
1494 };
1495 static const true_false_string tfs_file_attribute_offline = {
1496         "This file is OFFLINE",
1497         "This file is NOT offline"
1498 };
1499 static const true_false_string tfs_file_attribute_not_content_indexed = {
1500         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1501         "This file MAY be indexed by the content indexing service"
1502 };
1503 static const true_false_string tfs_file_attribute_encrypted = {
1504         "This is an ENCRYPTED file",
1505         "This is NOT an encrypted file"
1506 };
1507
1508 /*
1509  * In some places in the CIFS_TR_1p00.pdf, from SNIA, file attributes are 
1510  * listed as USHORT, and seem to be in packets in the wild, while in other
1511  * places they are listed as ULONG, and also seem to be.
1512  *
1513  * So, I (Richard Sharpe), added a parameter to allow us to specify how many
1514  * bytes to consume.
1515  */
1516
1517 static int
1518 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1519                         int bytes)
1520 {
1521         guint16 mask;
1522         proto_item *item = NULL;
1523         proto_tree *tree = NULL;
1524
1525         if (bytes != 2 && bytes != 4) {
1526
1527                 fprintf(stderr, "Incorrect number of bytes passed to dissect_file_attributes.\nMust be 2 or 4, was %d\n", bytes);
1528                 exit(1);
1529
1530         }
1531
1532         /*
1533          * The actual bits of interest appear to only be a USHORT
1534          */
1535         /* FIXME if this ever changes! */
1536         mask = tvb_get_letohs(tvb, offset);
1537
1538         if(parent_tree){
1539                 item = proto_tree_add_text(parent_tree, tvb, offset, bytes,
1540                         "File Attributes: 0x%08x", mask);
1541                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1542         }
1543         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted, 
1544                                tvb, offset, bytes, mask);       
1545         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed, 
1546                                tvb, offset, bytes, mask);
1547         proto_tree_add_boolean(tree, hf_smb_file_attr_offline, 
1548                                tvb, offset, bytes, mask);
1549         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed, 
1550                                tvb, offset, bytes, mask);
1551         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse, 
1552                                tvb, offset, bytes, mask);
1553         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse, 
1554                                tvb, offset, bytes, mask);
1555         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary, 
1556                                tvb, offset, bytes, mask);
1557         proto_tree_add_boolean(tree, hf_smb_file_attr_normal, 
1558                                tvb, offset, bytes, mask);
1559         proto_tree_add_boolean(tree, hf_smb_file_attr_device, 
1560                                tvb, offset, bytes, mask);
1561         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1562                 tvb, offset, bytes, mask);
1563         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1564                 tvb, offset, bytes, mask);
1565         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1566                 tvb, offset, bytes, mask);
1567         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1568                 tvb, offset, bytes, mask);
1569         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1570                 tvb, offset, bytes, mask);
1571         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1572                 tvb, offset, bytes, mask);
1573
1574         offset += bytes;
1575
1576         return offset;
1577 }
1578
1579 /* 3.11 */
1580 static int
1581 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1582 {
1583         guint32 mask;
1584         proto_item *item = NULL;
1585         proto_tree *tree = NULL;
1586
1587         mask = tvb_get_letohl(tvb, offset);
1588
1589         if(parent_tree){
1590                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1591                         "File Attributes: 0x%08x", mask);
1592                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1593         }
1594
1595         /*
1596          * XXX - Network Monitor disagrees on some of the
1597          * bits, e.g. the bits above temporary are "atomic write"
1598          * and "transaction write", and it says nothing about the
1599          * bits above that.
1600          *
1601          * Does the Win32 API documentation, or the NT Native API book,
1602          * suggest anything?
1603          */
1604         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1605                 tvb, offset, 4, mask);
1606         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1607                 tvb, offset, 4, mask);
1608         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1609                 tvb, offset, 4, mask);
1610         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1611                 tvb, offset, 4, mask);
1612         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1613                 tvb, offset, 4, mask);
1614         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1615                 tvb, offset, 4, mask);
1616         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1617                 tvb, offset, 4, mask);
1618         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1619                 tvb, offset, 4, mask);
1620         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1621                 tvb, offset, 4, mask);
1622         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1623                 tvb, offset, 4, mask);
1624         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1625                 tvb, offset, 4, mask);
1626         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1627                 tvb, offset, 4, mask);
1628         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1629                 tvb, offset, 4, mask);
1630         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1631                 tvb, offset, 4, mask);
1632         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1633                 tvb, offset, 4, mask);
1634
1635         offset += 4;
1636
1637         return offset;
1638 }
1639
1640 static int
1641 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1642 {
1643         guint8 mask;
1644         proto_item *item = NULL;
1645         proto_tree *tree = NULL;
1646
1647         mask = tvb_get_guint8(tvb, offset);
1648
1649         if(parent_tree){
1650                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1651                         "File Attributes: 0x%02x", mask);
1652                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1653         }
1654         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1655                 tvb, offset, 1, mask);
1656         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1657                 tvb, offset, 1, mask);
1658         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1659                 tvb, offset, 1, mask);
1660         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1661                 tvb, offset, 1, mask);
1662         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1663                 tvb, offset, 1, mask);
1664         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1665                 tvb, offset, 1, mask);
1666
1667         offset += 1;
1668
1669         return offset;
1670 }
1671
1672 static const true_false_string tfs_search_attribute_read_only = {
1673         "Include READ ONLY files in search results",
1674         "Do NOT include read only files in search results",
1675 };
1676 static const true_false_string tfs_search_attribute_hidden = {
1677         "Include HIDDEN files in search results",
1678         "Do NOT include hidden files in search results"
1679 };
1680 static const true_false_string tfs_search_attribute_system = {
1681         "Include SYSTEM files in search results",
1682         "Do NOT include system files in search results"
1683 };
1684 static const true_false_string tfs_search_attribute_volume = {
1685         "Include VOLUME IDs in search results",
1686         "Do NOT include volume IDs in search results"
1687 };
1688 static const true_false_string tfs_search_attribute_directory = {
1689         "Include DIRECTORIES in search results",
1690         "Do NOT include directories in search results"
1691 };
1692 static const true_false_string tfs_search_attribute_archive = {
1693         "Include ARCHIVE files in search results",
1694         "Do NOT include archive files in search results"
1695 };
1696
1697 static int
1698 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1699 {
1700         guint16 mask;
1701         proto_item *item = NULL;
1702         proto_tree *tree = NULL;
1703
1704         mask = tvb_get_letohs(tvb, offset);
1705
1706         if(parent_tree){
1707                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1708                         "Search Attributes: 0x%04x", mask);
1709                 tree = proto_item_add_subtree(item, ett_smb_search);
1710         }
1711
1712         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1713                 tvb, offset, 2, mask);
1714         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1715                 tvb, offset, 2, mask);
1716         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1717                 tvb, offset, 2, mask);
1718         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1719                 tvb, offset, 2, mask);
1720         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1721                 tvb, offset, 2, mask);
1722         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1723                 tvb, offset, 2, mask);
1724
1725         offset += 2;
1726         return offset;
1727 }
1728
1729 #if 0
1730 /*
1731  * XXX - this isn't used.
1732  * Is this used for anything?  NT Create AndX doesn't use it.
1733  * Is there some 16-bit attribute field with more bits than Read Only,
1734  * Hidden, System, Volume ID, Directory, and Archive?
1735  */
1736 static int
1737 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1738 {
1739         guint32 mask;
1740         proto_item *item = NULL;
1741         proto_tree *tree = NULL;
1742
1743         mask = tvb_get_letohl(tvb, offset);
1744
1745         if(parent_tree){
1746                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1747                         "File Attributes: 0x%08x", mask);
1748                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1749         }
1750         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1751                 tvb, offset, 2, mask);
1752         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1753                 tvb, offset, 2, mask);
1754         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1755                 tvb, offset, 2, mask);
1756         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1757                 tvb, offset, 2, mask);
1758         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1759                 tvb, offset, 2, mask);
1760         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1761                 tvb, offset, 2, mask);
1762         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1763                 tvb, offset, 2, mask);
1764         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1765                 tvb, offset, 2, mask);
1766         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1767                 tvb, offset, 2, mask);
1768         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1769                 tvb, offset, 2, mask);
1770         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1771                 tvb, offset, 2, mask);
1772         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1773                 tvb, offset, 2, mask);
1774         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1775                 tvb, offset, 2, mask);
1776         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1777                 tvb, offset, 2, mask);
1778         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1779                 tvb, offset, 2, mask);
1780
1781         offset += 2;
1782
1783         return offset;
1784 }
1785 #endif
1786
1787
1788 #define SERVER_CAP_RAW_MODE            0x00000001
1789 #define SERVER_CAP_MPX_MODE            0x00000002
1790 #define SERVER_CAP_UNICODE             0x00000004
1791 #define SERVER_CAP_LARGE_FILES         0x00000008
1792 #define SERVER_CAP_NT_SMBS             0x00000010
1793 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1794 #define SERVER_CAP_STATUS32            0x00000040
1795 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1796 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1797 #define SERVER_CAP_NT_FIND             0x00000200
1798 #define SERVER_CAP_DFS                 0x00001000
1799 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1800 #define SERVER_CAP_LARGE_READX         0x00004000
1801 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1802 #define SERVER_CAP_UNIX                0x00800000
1803 #define SERVER_CAP_RESERVED            0x02000000
1804 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1805 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1806 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1807 static const true_false_string tfs_server_cap_raw_mode = {
1808         "Read Raw and Write Raw are supported",
1809         "Read Raw and Write Raw are not supported"
1810 };
1811 static const true_false_string tfs_server_cap_mpx_mode = {
1812         "Read Mpx and Write Mpx are supported",
1813         "Read Mpx and Write Mpx are not supported"
1814 };
1815 static const true_false_string tfs_server_cap_unicode = {
1816         "Unicode strings are supported",
1817         "Unicode strings are not supported"
1818 };
1819 static const true_false_string tfs_server_cap_large_files = {
1820         "Large files are supported",
1821         "Large files are not supported",
1822 };
1823 static const true_false_string tfs_server_cap_nt_smbs = {
1824         "NT SMBs are supported",
1825         "NT SMBs are not supported"
1826 };
1827 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1828         "RPC remote APIs are supported",
1829         "RPC remote APIs are not supported"
1830 };
1831 static const true_false_string tfs_server_cap_nt_status = {
1832         "NT status codes are supported",
1833         "NT status codes are not supported"
1834 };
1835 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1836         "Level 2 oplocks are supported",
1837         "Level 2 oplocks are not supported"
1838 };
1839 static const true_false_string tfs_server_cap_lock_and_read = {
1840         "Lock and Read is supported",
1841         "Lock and Read is not supported"
1842 };
1843 static const true_false_string tfs_server_cap_nt_find = {
1844         "NT Find is supported",
1845         "NT Find is not supported"
1846 };
1847 static const true_false_string tfs_server_cap_dfs = {
1848         "Dfs is supported",
1849         "Dfs is not supported"
1850 };
1851 static const true_false_string tfs_server_cap_infolevel_passthru = {
1852         "NT information level request passthrough is supported",
1853         "NT information level request passthrough is not supported"
1854 };
1855 static const true_false_string tfs_server_cap_large_readx = {
1856         "Large Read andX is supported",
1857         "Large Read andX is not supported"
1858 };
1859 static const true_false_string tfs_server_cap_large_writex = {
1860         "Large Write andX is supported",
1861         "Large Write andX is not supported"
1862 };
1863 static const true_false_string tfs_server_cap_unix = {
1864         "UNIX extensions are supported",
1865         "UNIX extensions are not supported"
1866 };
1867 static const true_false_string tfs_server_cap_reserved = {
1868         "Reserved",
1869         "Reserved"
1870 };
1871 static const true_false_string tfs_server_cap_bulk_transfer = {
1872         "Bulk Read and Bulk Write are supported",
1873         "Bulk Read and Bulk Write are not supported"
1874 };
1875 static const true_false_string tfs_server_cap_compressed_data = {
1876         "Compressed data transfer is supported",
1877         "Compressed data transfer is not supported"
1878 };
1879 static const true_false_string tfs_server_cap_extended_security = {
1880         "Extended security exchanges are supported",
1881         "Extended security exchanges are not supported"
1882 };
1883 static int
1884 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1885 {
1886         guint32 mask;
1887         proto_item *item = NULL;
1888         proto_tree *tree = NULL;
1889
1890         mask = tvb_get_letohl(tvb, offset);
1891
1892         if(parent_tree){
1893                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1894                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1895         }
1896
1897         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1898                 tvb, offset, 4, mask);
1899         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1900                 tvb, offset, 4, mask);
1901         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1902                 tvb, offset, 4, mask);
1903         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1904                 tvb, offset, 4, mask);
1905         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1906                 tvb, offset, 4, mask);
1907         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1908                 tvb, offset, 4, mask);
1909         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1910                 tvb, offset, 4, mask);
1911         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1912                 tvb, offset, 4, mask);
1913         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1914                 tvb, offset, 4, mask);
1915         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1916                 tvb, offset, 4, mask);
1917         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1918                 tvb, offset, 4, mask);
1919         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1920                 tvb, offset, 4, mask);
1921         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1922                 tvb, offset, 4, mask);
1923         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1924                 tvb, offset, 4, mask);
1925         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1926                 tvb, offset, 4, mask);
1927         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1928                 tvb, offset, 4, mask);
1929         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1930                 tvb, offset, 4, mask);
1931         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1932                 tvb, offset, 4, mask);
1933         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1934                 tvb, offset, 4, mask);
1935
1936         return mask;
1937 }
1938
1939 #define RAWMODE_READ   0x01
1940 #define RAWMODE_WRITE  0x02
1941 static const true_false_string tfs_rm_read = {
1942         "Read Raw is supported",
1943         "Read Raw is not supported"
1944 };
1945 static const true_false_string tfs_rm_write = {
1946         "Write Raw is supported",
1947         "Write Raw is not supported"
1948 };
1949
1950 static int
1951 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1952 {
1953         guint16 mask;
1954         proto_item *item = NULL;
1955         proto_tree *tree = NULL;
1956
1957         mask = tvb_get_letohs(tvb, offset);
1958
1959         if(parent_tree){
1960                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1961                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1962         }
1963
1964         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
1965         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
1966
1967         offset += 2;
1968
1969         return offset;
1970 }
1971
1972 #define SECURITY_MODE_MODE             0x01
1973 #define SECURITY_MODE_PASSWORD         0x02
1974 #define SECURITY_MODE_SIGNATURES       0x04
1975 #define SECURITY_MODE_SIG_REQUIRED     0x08
1976 static const true_false_string tfs_sm_mode = {
1977         "USER security mode",
1978         "SHARE security mode"
1979 };
1980 static const true_false_string tfs_sm_password = {
1981         "ENCRYPTED password. Use challenge/response",
1982         "PLAINTEXT password"
1983 };
1984 static const true_false_string tfs_sm_signatures = {
1985         "Security signatures ENABLED",
1986         "Security signatures NOT enabled"
1987 };
1988 static const true_false_string tfs_sm_sig_required = {
1989         "Security signatures REQUIRED",
1990         "Security signatures NOT required"
1991 };
1992
1993 static int
1994 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
1995 {
1996         guint16 mask = 0;
1997         proto_item *item = NULL;
1998         proto_tree *tree = NULL;
1999
2000         switch(wc){
2001         case 13:
2002                 mask = tvb_get_letohs(tvb, offset);
2003                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2004                                 "Security Mode: 0x%04x", mask);
2005                 tree = proto_item_add_subtree(item, ett_smb_mode);
2006                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
2007                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
2008                 offset += 2;
2009                 break;
2010
2011         case 17:
2012                 mask = tvb_get_guint8(tvb, offset);
2013                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
2014                                 "Security Mode: 0x%02x", mask);
2015                 tree = proto_item_add_subtree(item, ett_smb_mode);
2016                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2017                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2018                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2019                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2020                 offset += 1;
2021                 break;
2022         }
2023
2024         return offset;
2025 }
2026
2027 static int
2028 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2029 {
2030         proto_item *it = NULL;
2031         proto_tree *tr = NULL;
2032         guint16 bc;
2033         guint8 wc;
2034
2035         WORD_COUNT;
2036
2037         BYTE_COUNT;
2038
2039         if(tree){
2040                 it = proto_tree_add_text(tree, tvb, offset, bc,
2041                                 "Requested Dialects");
2042                 tr = proto_item_add_subtree(it, ett_smb_dialects);
2043         }
2044
2045         while(bc){
2046                 int len;
2047                 const guint8 *str;
2048                 proto_item *dit = NULL;
2049                 proto_tree *dtr = NULL;
2050
2051                 /* XXX - what if this runs past bc? */
2052                 len = tvb_strsize(tvb, offset+1);
2053                 str = tvb_get_ptr(tvb, offset+1, len);
2054
2055                 if(tr){
2056                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2057                                         "Dialect: %s", str);
2058                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2059                 }
2060
2061                 /* Buffer Format */
2062                 CHECK_BYTE_COUNT(1);
2063                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2064                         TRUE);
2065                 COUNT_BYTES(1);
2066
2067                 /*Dialect Name */
2068                 CHECK_BYTE_COUNT(len);
2069                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2070                         len, str);
2071                 COUNT_BYTES(len);
2072         }
2073
2074         END_OF_SMB
2075
2076         return offset;
2077 }
2078
2079 static int
2080 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2081 {
2082         smb_info_t *si = pinfo->private_data;
2083         guint8 wc;
2084         guint16 dialect;
2085         const char *dn;
2086         int dn_len;
2087         guint16 bc;
2088         guint16 ekl=0;
2089         guint32 caps=0;
2090         gint16 tz;
2091
2092         WORD_COUNT;
2093
2094         /* Dialect Index */
2095         dialect = tvb_get_letohs(tvb, offset);
2096         switch(wc){
2097         case 1:
2098                 if(dialect==0xffff){
2099                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2100                                 tvb, offset, 2, dialect,
2101                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2102                 } else {
2103                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2104                                 tvb, offset, 2, dialect);
2105                 }
2106                 break;
2107         case 13:
2108                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2109                         tvb, offset, 2, dialect,
2110                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2111                 break;
2112         case 17:
2113                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2114                         tvb, offset, 2, dialect,
2115                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2116                 break;
2117         default:
2118                 proto_tree_add_text(tree, tvb, offset, wc*2,
2119                         "Words for unknown response format");
2120                 offset += wc*2;
2121                 goto bytecount;
2122         }
2123         offset += 2;
2124
2125         switch(wc){
2126         case 13:
2127                 /* Security Mode */
2128                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2129
2130                 /* Maximum Transmit Buffer Size */
2131                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2132                         tvb, offset, 2, TRUE);
2133                 offset += 2;
2134
2135                 /* Maximum Multiplex Count */
2136                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2137                         tvb, offset, 2, TRUE);
2138                 offset += 2;
2139
2140                 /* Maximum Vcs Number */
2141                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2142                         tvb, offset, 2, TRUE);
2143                 offset += 2;
2144
2145                 /* raw mode */
2146                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2147
2148                 /* session key */
2149                 proto_tree_add_item(tree, hf_smb_session_key,
2150                         tvb, offset, 4, TRUE);
2151                 offset += 4;
2152
2153                 /* current time and date at server */
2154                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2155                     TRUE);
2156
2157                 /* time zone */
2158                 tz = tvb_get_letohs(tvb, offset);
2159                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2160                 offset += 2;
2161
2162                 /* encryption key length */
2163                 ekl = tvb_get_letohs(tvb, offset);
2164                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2165                 offset += 2;
2166
2167                 /* 2 reserved bytes */
2168                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2169                 offset += 2;
2170
2171                 break;
2172
2173         case 17:
2174                 /* Security Mode */
2175                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2176
2177                 /* Maximum Multiplex Count */
2178                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2179                         tvb, offset, 2, TRUE);
2180                 offset += 2;
2181
2182                 /* Maximum Vcs Number */
2183                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2184                         tvb, offset, 2, TRUE);
2185                 offset += 2;
2186
2187                 /* Maximum Transmit Buffer Size */
2188                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2189                         tvb, offset, 4, TRUE);
2190                 offset += 4;
2191
2192                 /* maximum raw buffer size */
2193                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2194                         tvb, offset, 4, TRUE);
2195                 offset += 4;
2196
2197                 /* session key */
2198                 proto_tree_add_item(tree, hf_smb_session_key,
2199                         tvb, offset, 4, TRUE);
2200                 offset += 4;
2201
2202                 /* server capabilities */
2203                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2204                 offset += 4;
2205
2206                 /* system time */
2207                 offset = dissect_smb_64bit_time(tvb, tree, offset,
2208                                 hf_smb_system_time);
2209
2210                 /* time zone */
2211                 tz = tvb_get_letohs(tvb, offset);
2212                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2213                         tvb, offset, 2, tz,
2214                         "Server Time Zone: %d min from UTC", tz);
2215                 offset += 2;
2216
2217                 /* encryption key length */
2218                 ekl = tvb_get_guint8(tvb, offset);
2219                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2220                         tvb, offset, 1, ekl);
2221                 offset += 1;
2222
2223                 break;
2224         }
2225
2226         BYTE_COUNT;
2227
2228         switch(wc){
2229         case 13:
2230                 /* challenge/response encryption key */
2231                 if(ekl){
2232                         CHECK_BYTE_COUNT(ekl);
2233                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2234                         COUNT_BYTES(ekl);
2235                 }
2236
2237                 /*
2238                  * Primary domain.
2239                  *
2240                  * XXX - not present if negotiated dialect isn't
2241                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2242                  * have to see the request, or assume what dialect strings
2243                  * were sent, to determine that.
2244                  *
2245                  * Is this something other than a primary domain if the
2246                  * negotiated dialect is Windows for Workgroups 3.1a?
2247                  * It appears to be 8 bytes of binary data in at least
2248                  * one capture - is that an encryption key or something
2249                  * such as that?
2250                  */
2251                 dn = get_unicode_or_ascii_string(tvb, &offset,
2252                         si->unicode, &dn_len, FALSE, FALSE, &bc);
2253                 if (dn == NULL)
2254                         goto endofcommand;
2255                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2256                         offset, dn_len,dn);
2257                 COUNT_BYTES(dn_len);
2258                 break;
2259
2260         case 17:
2261                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2262                         /* challenge/response encryption key */
2263                         /* XXX - is this aligned on an even boundary? */
2264                         if(ekl){
2265                                 CHECK_BYTE_COUNT(ekl);
2266                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2267                                         tvb, offset, ekl, TRUE);
2268                                 COUNT_BYTES(ekl);
2269                         }
2270
2271                         /* domain */
2272                         /* this string is special, unicode is flagged in caps */
2273                         /* This string is NOT padded to be 16bit aligned.
2274                            (seen in actual capture)
2275                            XXX - I've seen a capture where it appears to be
2276                            so aligned, but I've also seen captures where
2277                            it is.  The captures where it appeared to be
2278                            aligned may have been from buggy servers. */
2279                         /* However, don't get rid of existing setting */
2280                         si->unicode = (caps&SERVER_CAP_UNICODE) ||
2281                           si->unicode;
2282
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_primary_domain,
2289                                 tvb, offset, dn_len, dn);
2290                         COUNT_BYTES(dn_len);
2291
2292                         /* server name, seen in w2k pro capture */
2293                         dn = get_unicode_or_ascii_string(tvb,
2294                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2295                                 &bc);
2296                         if (dn == NULL)
2297                                 goto endofcommand;
2298                         proto_tree_add_string(tree, hf_smb_server,
2299                                 tvb, offset, dn_len, dn);
2300                         COUNT_BYTES(dn_len);
2301
2302                 } else {
2303                         proto_item *blob_item;
2304
2305                         /* guid */
2306                         /* XXX - show it in the standard Microsoft format
2307                            for GUIDs? */
2308                         CHECK_BYTE_COUNT(16);
2309                         proto_tree_add_item(tree, hf_smb_server_guid,
2310                                 tvb, offset, 16, TRUE);
2311                         COUNT_BYTES(16);
2312
2313                         blob_item = proto_tree_add_item(
2314                                 tree, hf_smb_security_blob,
2315                                 tvb, offset, bc, TRUE);
2316
2317                         /* security blob */
2318                         /* 
2319                          * If Extended security and BCC == 16, then raw 
2320                          * NTLMSSP is in use. We need to save this info
2321                          */
2322  
2323                         if(bc){
2324                                 tvbuff_t *gssapi_tvb;
2325                                 proto_tree *gssapi_tree;
2326
2327                                 gssapi_tree = proto_item_add_subtree(
2328                                         blob_item, ett_smb_secblob);
2329
2330                                 gssapi_tvb = tvb_new_subset(
2331                                         tvb, offset, bc, bc);
2332
2333                                 call_dissector(
2334                                         gssapi_handle, gssapi_tvb, pinfo,
2335                                         gssapi_tree);
2336
2337                                 if (si->ct)
2338                                   si->ct->raw_ntlmssp = 0;
2339
2340                                 COUNT_BYTES(bc);
2341                         }
2342                         else { 
2343
2344                           /*
2345                            * There is no blob. We just have to make sure
2346                            * that subsequent routines know to call the 
2347                            * right things ...
2348                            */
2349
2350                           if (si->ct)
2351                             si->ct->raw_ntlmssp = 1;
2352
2353                         }
2354                 }
2355                 break;
2356         }
2357
2358         END_OF_SMB
2359
2360         return offset;
2361 }
2362
2363
2364 static int
2365 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2366 {
2367         smb_info_t *si = pinfo->private_data;
2368         int dn_len;
2369         const char *dn;
2370         guint8 wc;
2371         guint16 bc;
2372
2373         WORD_COUNT;
2374
2375         BYTE_COUNT;
2376
2377         /* buffer format */
2378         CHECK_BYTE_COUNT(1);
2379         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2380         COUNT_BYTES(1);
2381
2382         /* dir name */
2383         dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
2384                 FALSE, FALSE, &bc);
2385         if (dn == NULL)
2386                 goto endofcommand;
2387         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2388                 dn);
2389         COUNT_BYTES(dn_len);
2390
2391         if (check_col(pinfo->cinfo, COL_INFO)) {
2392                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s", dn);
2393         }
2394
2395         END_OF_SMB
2396
2397         return offset;
2398 }
2399
2400 static int
2401 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2402 {
2403         guint8 wc;
2404         guint16 bc;
2405
2406         WORD_COUNT;
2407
2408         BYTE_COUNT;
2409
2410         END_OF_SMB
2411
2412         return offset;
2413 }
2414
2415 static int
2416 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2417 {
2418         guint16 ec, bc;
2419         guint8 wc;
2420
2421         WORD_COUNT;
2422
2423         /* echo count */
2424         ec = tvb_get_letohs(tvb, offset);
2425         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2426         offset += 2;
2427
2428         BYTE_COUNT;
2429
2430         if (bc != 0) {
2431                 /* echo data */
2432                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2433                 COUNT_BYTES(bc);
2434         }
2435
2436         END_OF_SMB
2437
2438         return offset;
2439 }
2440
2441 static int
2442 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2443 {
2444         guint16 bc;
2445         guint8 wc;
2446
2447         WORD_COUNT;
2448
2449         /* echo sequence number */
2450         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2451         offset += 2;
2452
2453         BYTE_COUNT;
2454
2455         if (bc != 0) {
2456                 /* echo data */
2457                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2458                 COUNT_BYTES(bc);
2459         }
2460
2461         END_OF_SMB
2462
2463         return offset;
2464 }
2465
2466 static int
2467 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2468 {
2469         smb_info_t *si = pinfo->private_data;
2470         int an_len, pwlen;
2471         const char *an;
2472         guint8 wc;
2473         guint16 bc;
2474
2475         WORD_COUNT;
2476
2477         BYTE_COUNT;
2478
2479         /* buffer format */
2480         CHECK_BYTE_COUNT(1);
2481         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2482         COUNT_BYTES(1);
2483
2484         /* Path */
2485         an = get_unicode_or_ascii_string(tvb, &offset,
2486                 si->unicode, &an_len, FALSE, FALSE, &bc);
2487         if (an == NULL)
2488                 goto endofcommand;
2489         proto_tree_add_string(tree, hf_smb_path, tvb,
2490                 offset, an_len, an);
2491         COUNT_BYTES(an_len);
2492
2493         if (check_col(pinfo->cinfo, COL_INFO)) {
2494                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
2495         }
2496
2497         /* buffer format */
2498         CHECK_BYTE_COUNT(1);
2499         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2500         COUNT_BYTES(1);
2501
2502         /* password, ANSI */
2503         /* XXX - what if this runs past bc? */
2504         pwlen = tvb_strsize(tvb, offset);
2505         CHECK_BYTE_COUNT(pwlen);
2506         proto_tree_add_item(tree, hf_smb_password,
2507                 tvb, offset, pwlen, TRUE);
2508         COUNT_BYTES(pwlen);
2509
2510         /* buffer format */
2511         CHECK_BYTE_COUNT(1);
2512         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2513         COUNT_BYTES(1);
2514
2515         /* Service */
2516         an = get_unicode_or_ascii_string(tvb, &offset,
2517                 si->unicode, &an_len, FALSE, FALSE, &bc);
2518         if (an == NULL)
2519                 goto endofcommand;
2520         proto_tree_add_string(tree, hf_smb_service, tvb,
2521                 offset, an_len, an);
2522         COUNT_BYTES(an_len);
2523
2524         END_OF_SMB
2525
2526         return offset;
2527 }
2528
2529 static int
2530 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2531 {
2532         guint8 wc;
2533         guint16 bc;
2534
2535         WORD_COUNT;
2536
2537         /* Maximum Buffer Size */
2538         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2539         offset += 2;
2540
2541         /* tid */
2542         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2543         offset += 2;
2544
2545         BYTE_COUNT;
2546
2547         END_OF_SMB
2548
2549         return offset;
2550 }
2551
2552
2553 static const true_false_string tfs_of_create = {
2554         "Create file if it does not exist",
2555         "Fail if file does not exist"
2556 };
2557 static const value_string of_open[] = {
2558         { 0,            "Fail if file exists"},
2559         { 1,            "Open file if it exists"},
2560         { 2,            "Truncate file if it exists"},
2561         {0, NULL}
2562 };
2563 static int
2564 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2565 {
2566         guint16 mask;
2567         proto_item *item = NULL;
2568         proto_tree *tree = NULL;
2569
2570         mask = tvb_get_letohs(tvb, offset);
2571
2572         if(parent_tree){
2573                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2574                         "Open Function: 0x%04x", mask);
2575                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2576         }
2577
2578         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2579                 tvb, offset, 2, mask);
2580         proto_tree_add_uint(tree, hf_smb_open_function_open,
2581                 tvb, offset, 2, mask);
2582
2583         offset += 2;
2584
2585         return offset;
2586 }
2587
2588
2589 static const true_false_string tfs_mf_file = {
2590         "Target must be a file",
2591         "Target needn't be a file"
2592 };
2593 static const true_false_string tfs_mf_dir = {
2594         "Target must be a directory",
2595         "Target needn't be a directory"
2596 };
2597 static const true_false_string tfs_mf_verify = {
2598         "MUST verify all writes",
2599         "Don't have to verify writes"
2600 };
2601 static int
2602 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2603 {
2604         guint16 mask;
2605         proto_item *item = NULL;
2606         proto_tree *tree = NULL;
2607
2608         mask = tvb_get_letohs(tvb, offset);
2609
2610         if(parent_tree){
2611                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2612                         "Flags: 0x%04x", mask);
2613                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2614         }
2615
2616         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2617                 tvb, offset, 2, mask);
2618         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2619                 tvb, offset, 2, mask);
2620         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2621                 tvb, offset, 2, mask);
2622
2623         offset += 2;
2624
2625         return offset;
2626 }
2627
2628 static const true_false_string tfs_cf_mode = {
2629         "ASCII",
2630         "Binary"
2631 };
2632 static const true_false_string tfs_cf_tree_copy = {
2633         "Copy is a tree copy",
2634         "Copy is a file copy"
2635 };
2636 static const true_false_string tfs_cf_ea_action = {
2637         "Fail copy",
2638         "Discard EAs"
2639 };
2640 static int
2641 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2642 {
2643         guint16 mask;
2644         proto_item *item = NULL;
2645         proto_tree *tree = NULL;
2646
2647         mask = tvb_get_letohs(tvb, offset);
2648
2649         if(parent_tree){
2650                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2651                         "Flags: 0x%04x", mask);
2652                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2653         }
2654
2655         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
2656                 tvb, offset, 2, mask);
2657         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2658                 tvb, offset, 2, mask);
2659         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2660                 tvb, offset, 2, mask);
2661         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2662                 tvb, offset, 2, mask);
2663         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2664                 tvb, offset, 2, mask);
2665         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2666                 tvb, offset, 2, mask);
2667         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2668                 tvb, offset, 2, mask);
2669
2670         offset += 2;
2671
2672         return offset;
2673 }
2674
2675 static int
2676 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2677 {
2678         smb_info_t *si = pinfo->private_data;
2679         int fn_len;
2680         guint16 tid;
2681         guint16 bc;
2682         guint8 wc;
2683         const char *fn;
2684
2685         WORD_COUNT;
2686
2687         /* tid */
2688         tid = tvb_get_letohs(tvb, offset);
2689         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2690                 "TID (target): 0x%04x", tid);
2691         offset += 2;
2692
2693         /* open function */
2694         offset = dissect_open_function(tvb, tree, offset);
2695
2696         /* move flags */
2697         offset = dissect_move_flags(tvb, tree, offset);
2698
2699         BYTE_COUNT;
2700
2701         /* buffer format */
2702         CHECK_BYTE_COUNT(1);
2703         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2704         COUNT_BYTES(1);
2705
2706         /* file name */
2707         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2708                 FALSE, FALSE, &bc);
2709         if (fn == NULL)
2710                 goto endofcommand;
2711         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2712                 fn_len, fn, "Old File Name: %s", fn);
2713         COUNT_BYTES(fn_len);
2714
2715         if (check_col(pinfo->cinfo, COL_INFO)) {
2716                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2717         }
2718
2719         /* buffer format */
2720         CHECK_BYTE_COUNT(1);
2721         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2722         COUNT_BYTES(1);
2723
2724         /* file name */
2725         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2726                 FALSE, FALSE, &bc);
2727         if (fn == NULL)
2728                 goto endofcommand;
2729         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2730                 fn_len, fn, "New File Name: %s", fn);
2731         COUNT_BYTES(fn_len);
2732
2733         if (check_col(pinfo->cinfo, COL_INFO)) {
2734                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2735         }
2736
2737         END_OF_SMB
2738
2739         return offset;
2740 }
2741
2742 static int
2743 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2744 {
2745         smb_info_t *si = pinfo->private_data;
2746         int fn_len;
2747         guint16 tid;
2748         guint16 bc;
2749         guint8 wc;
2750         const char *fn;
2751
2752         WORD_COUNT;
2753
2754         /* tid */
2755         tid = tvb_get_letohs(tvb, offset);
2756         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2757                 "TID (target): 0x%04x", tid);
2758         offset += 2;
2759
2760         /* open function */
2761         offset = dissect_open_function(tvb, tree, offset);
2762
2763         /* copy flags */
2764         offset = dissect_copy_flags(tvb, tree, offset);
2765
2766         BYTE_COUNT;
2767
2768         /* buffer format */
2769         CHECK_BYTE_COUNT(1);
2770         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2771         COUNT_BYTES(1);
2772
2773         /* file name */
2774         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2775                 FALSE, FALSE, &bc);
2776         if (fn == NULL)
2777                 goto endofcommand;
2778         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2779                 fn_len, fn, "Source File Name: %s", fn);
2780         COUNT_BYTES(fn_len);
2781
2782         if (check_col(pinfo->cinfo, COL_INFO)) {
2783                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s", fn);
2784         }
2785
2786         /* buffer format */
2787         CHECK_BYTE_COUNT(1);
2788         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2789         COUNT_BYTES(1);
2790
2791         /* file name */
2792         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2793                 FALSE, FALSE, &bc);
2794         if (fn == NULL)
2795                 goto endofcommand;
2796         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2797                 fn_len, fn, "Destination File Name: %s", fn);
2798         COUNT_BYTES(fn_len);
2799
2800         if (check_col(pinfo->cinfo, COL_INFO)) {
2801                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", fn);
2802         }
2803
2804         END_OF_SMB
2805
2806         return offset;
2807 }
2808
2809 static int
2810 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2811 {
2812         smb_info_t *si = pinfo->private_data;
2813         int fn_len;
2814         const char *fn;
2815         guint8 wc;
2816         guint16 bc;
2817
2818         WORD_COUNT;
2819
2820         /* # of files moved */
2821         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
2822         offset += 2;
2823
2824         BYTE_COUNT;
2825
2826         /* buffer format */
2827         CHECK_BYTE_COUNT(1);
2828         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2829         COUNT_BYTES(1);
2830
2831         /* file name */
2832         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2833                 FALSE, FALSE, &bc);
2834         if (fn == NULL)
2835                 goto endofcommand;
2836         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2837                 fn);
2838         COUNT_BYTES(fn_len);
2839
2840         END_OF_SMB
2841
2842         return offset;
2843 }
2844
2845 static int
2846 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2847 {
2848         smb_info_t *si = pinfo->private_data;
2849         int fn_len;
2850         const char *fn;
2851         guint8 wc;
2852         guint16 bc;
2853
2854         WORD_COUNT;
2855
2856         /* desired access */
2857         offset = dissect_access(tvb, tree, offset, "Desired");
2858
2859         /* Search Attributes */
2860         offset = dissect_search_attributes(tvb, tree, offset);
2861
2862         BYTE_COUNT;
2863
2864         /* buffer format */
2865         CHECK_BYTE_COUNT(1);
2866         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2867         COUNT_BYTES(1);
2868
2869         /* file name */
2870         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2871                 FALSE, FALSE, &bc);
2872         if (fn == NULL)
2873                 goto endofcommand;
2874         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2875                 fn);
2876         COUNT_BYTES(fn_len);
2877
2878         if (check_col(pinfo->cinfo, COL_INFO)) {
2879                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2880         }
2881
2882         END_OF_SMB
2883
2884         return offset;
2885 }
2886
2887 void
2888 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2889     int len, guint16 fid)
2890 {
2891         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2892         if (check_col(pinfo->cinfo, COL_INFO))
2893                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2894 }
2895
2896 static int
2897 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2898 {
2899         guint8 wc;
2900         guint16 bc;
2901         guint16 fid;
2902
2903         WORD_COUNT;
2904
2905         /* fid */
2906         fid = tvb_get_letohs(tvb, offset);
2907         add_fid(tvb, pinfo, tree, offset, 2, fid);
2908         offset += 2;
2909
2910         /* File Attributes */
2911         offset = dissect_file_attributes(tvb, tree, offset, 2);
2912
2913         /* last write time */
2914         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2915
2916         /* File Size */
2917         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2918         offset += 4;
2919
2920         /* granted access */
2921         offset = dissect_access(tvb, tree, offset, "Granted");
2922
2923         BYTE_COUNT;
2924
2925         END_OF_SMB
2926
2927         return offset;
2928 }
2929
2930 static int
2931 dissect_fid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2932 {
2933         guint8 wc;
2934         guint16 bc;
2935         guint16 fid;
2936
2937         WORD_COUNT;
2938
2939         /* fid */
2940         fid = tvb_get_letohs(tvb, offset);
2941         add_fid(tvb, pinfo, tree, offset, 2, fid);
2942         offset += 2;
2943
2944         BYTE_COUNT;
2945
2946         END_OF_SMB
2947
2948         return offset;
2949 }
2950
2951 static int
2952 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2953 {
2954         smb_info_t *si = pinfo->private_data;
2955         int fn_len;
2956         const char *fn;
2957         guint8 wc;
2958         guint16 bc;
2959
2960         WORD_COUNT;
2961
2962         /* file attributes */
2963         offset = dissect_file_attributes(tvb, tree, offset, 2);
2964
2965         /* creation time */
2966         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
2967
2968         BYTE_COUNT;
2969
2970         /* buffer format */
2971         CHECK_BYTE_COUNT(1);
2972         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2973         COUNT_BYTES(1);
2974
2975         /* File Name */
2976         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2977                 FALSE, FALSE, &bc);
2978         if (fn == NULL)
2979                 goto endofcommand;
2980         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2981                 fn);
2982         COUNT_BYTES(fn_len);
2983
2984         if (check_col(pinfo->cinfo, COL_INFO)) {
2985                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2986         }
2987
2988         END_OF_SMB
2989
2990         return offset;
2991 }
2992
2993 static int
2994 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2995 {
2996         guint8 wc;
2997         guint16 bc, fid;
2998
2999         WORD_COUNT;
3000
3001         /* fid */
3002         fid = tvb_get_letohs(tvb, offset);
3003         add_fid(tvb, pinfo, tree, offset, 2, fid);
3004         offset += 2;
3005
3006         /* last write time */
3007         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3008
3009         BYTE_COUNT;
3010
3011         END_OF_SMB
3012
3013         return offset;
3014 }
3015
3016 static int
3017 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3018 {
3019         smb_info_t *si = pinfo->private_data;
3020         int fn_len;
3021         const char *fn;
3022         guint8 wc;
3023         guint16 bc;
3024
3025         WORD_COUNT;
3026
3027         /* search attributes */
3028         offset = dissect_search_attributes(tvb, tree, offset);
3029
3030         BYTE_COUNT;
3031
3032         /* buffer format */
3033         CHECK_BYTE_COUNT(1);
3034         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3035         COUNT_BYTES(1);
3036
3037         /* file name */
3038         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3039                 FALSE, FALSE, &bc);
3040         if (fn == NULL)
3041                 goto endofcommand;
3042         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3043                 fn);
3044         COUNT_BYTES(fn_len);
3045
3046         if (check_col(pinfo->cinfo, COL_INFO)) {
3047                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3048         }
3049
3050         END_OF_SMB
3051
3052         return offset;
3053 }
3054
3055 static int
3056 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3057 {
3058         smb_info_t *si = pinfo->private_data;
3059         int fn_len;
3060         const char *fn;
3061         guint8 wc;
3062         guint16 bc;
3063
3064         WORD_COUNT;
3065
3066         /* search attributes */
3067         offset = dissect_search_attributes(tvb, tree, offset);
3068
3069         BYTE_COUNT;
3070
3071         /* buffer format */
3072         CHECK_BYTE_COUNT(1);
3073         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3074         COUNT_BYTES(1);
3075
3076         /* old file name */
3077         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3078                 FALSE, FALSE, &bc);
3079         if (fn == NULL)
3080                 goto endofcommand;
3081         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3082                 fn);
3083         COUNT_BYTES(fn_len);
3084
3085         if (check_col(pinfo->cinfo, COL_INFO)) {
3086                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3087         }
3088
3089         /* buffer format */
3090         CHECK_BYTE_COUNT(1);
3091         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3092         COUNT_BYTES(1);
3093
3094         /* file name */
3095         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3096                 FALSE, FALSE, &bc);
3097         if (fn == NULL)
3098                 goto endofcommand;
3099         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3100                 fn);
3101         COUNT_BYTES(fn_len);
3102
3103         if (check_col(pinfo->cinfo, COL_INFO)) {
3104                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3105         }
3106
3107         END_OF_SMB
3108
3109         return offset;
3110 }
3111
3112 static int
3113 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3114 {
3115         smb_info_t *si = pinfo->private_data;
3116         int fn_len;
3117         const char *fn;
3118         guint8 wc;
3119         guint16 bc;
3120
3121         WORD_COUNT;
3122
3123         /* search attributes */
3124         offset = dissect_search_attributes(tvb, tree, offset);
3125
3126         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3127         offset += 2;
3128
3129         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3130         offset += 4;
3131
3132         BYTE_COUNT;
3133
3134         /* buffer format */
3135         CHECK_BYTE_COUNT(1);
3136         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3137         COUNT_BYTES(1);
3138
3139         /* old file name */
3140         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3141                 FALSE, FALSE, &bc);
3142         if (fn == NULL)
3143                 goto endofcommand;
3144         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3145                 fn);
3146         COUNT_BYTES(fn_len);
3147
3148         if (check_col(pinfo->cinfo, COL_INFO)) {
3149                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3150         }
3151
3152         /* buffer format */
3153         CHECK_BYTE_COUNT(1);
3154         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3155         COUNT_BYTES(1);
3156
3157         /* file name */
3158         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3159                 FALSE, FALSE, &bc);
3160         if (fn == NULL)
3161                 goto endofcommand;
3162         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3163                 fn);
3164         COUNT_BYTES(fn_len);
3165
3166         if (check_col(pinfo->cinfo, COL_INFO)) {
3167                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3168         }
3169
3170         END_OF_SMB
3171
3172         return offset;
3173 }
3174
3175
3176 static int
3177 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3178 {
3179         smb_info_t *si = pinfo->private_data;
3180         guint16 bc;
3181         guint8 wc;
3182         const char *fn;
3183         int fn_len;
3184
3185         WORD_COUNT;
3186
3187         BYTE_COUNT;
3188
3189         /* Buffer Format */
3190         CHECK_BYTE_COUNT(1);
3191         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3192         COUNT_BYTES(1);
3193
3194         /* File Name */
3195         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3196                 FALSE, FALSE, &bc);
3197         if (fn == NULL)
3198                 goto endofcommand;
3199         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3200                 fn);
3201         COUNT_BYTES(fn_len);
3202
3203         if (check_col(pinfo->cinfo, COL_INFO)) {
3204                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3205         }
3206
3207         END_OF_SMB
3208
3209         return offset;
3210 }
3211
3212 static int
3213 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3214 {
3215         guint16 bc;
3216         guint8 wc;
3217
3218         WORD_COUNT;
3219
3220         /* File Attributes */
3221         offset = dissect_file_attributes(tvb, tree, offset, 2);
3222
3223         /* Last Write Time */
3224         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3225
3226         /* File Size */
3227         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3228         offset += 4;
3229
3230         /* 10 reserved bytes */
3231         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3232         offset += 10;
3233
3234         BYTE_COUNT;
3235
3236         END_OF_SMB
3237
3238         return offset;
3239 }
3240
3241 static int
3242 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3243 {
3244         smb_info_t *si = pinfo->private_data;
3245         int fn_len;
3246         const char *fn;
3247         guint8 wc;
3248         guint16 bc;
3249
3250         WORD_COUNT;
3251
3252         /* file attributes */
3253         offset = dissect_file_attributes(tvb, tree, offset, 2);
3254
3255         /* last write time */
3256         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3257
3258         /* 10 reserved bytes */
3259         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3260         offset += 10;
3261
3262         BYTE_COUNT;
3263
3264         /* buffer format */
3265         CHECK_BYTE_COUNT(1);
3266         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3267         COUNT_BYTES(1);
3268
3269         /* file name */
3270         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3271                 FALSE, FALSE, &bc);
3272         if (fn == NULL)
3273                 goto endofcommand;
3274         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3275                 fn);
3276         COUNT_BYTES(fn_len);
3277
3278         if (check_col(pinfo->cinfo, COL_INFO)) {
3279                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3280         }
3281
3282         END_OF_SMB
3283
3284         return offset;
3285 }
3286
3287 static int
3288 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3289 {
3290         guint8 wc;
3291         guint16 cnt=0, bc;
3292         guint32 ofs=0;
3293         smb_info_t *si;
3294         unsigned int fid;
3295
3296         WORD_COUNT;
3297
3298         /* fid */
3299         fid = tvb_get_letohs(tvb, offset);
3300         add_fid(tvb, pinfo, tree, offset, 2, fid);
3301         offset += 2;
3302         if (!pinfo->fd->flags.visited) {
3303                 /* remember the FID for the processing of the response */
3304                 si = (smb_info_t *)pinfo->private_data;
3305                 si->sip->extra_info=(void *)fid;
3306         }
3307
3308         /* read count */
3309         cnt = tvb_get_letohs(tvb, offset);
3310         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3311         offset += 2;
3312
3313         /* offset */
3314         ofs = tvb_get_letohl(tvb, offset);
3315         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3316         offset += 4;
3317
3318         if (check_col(pinfo->cinfo, COL_INFO))
3319                 col_append_fstr(pinfo->cinfo, COL_INFO,
3320                                 ", %u byte%s at offset %u", cnt,
3321                                 (cnt == 1) ? "" : "s", ofs);
3322
3323         /* remaining */
3324         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3325         offset += 2;
3326
3327         BYTE_COUNT;
3328
3329         END_OF_SMB
3330
3331         return offset;
3332 }
3333
3334 int
3335 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3336 {
3337         int tvblen;
3338
3339         if(bc>datalen){
3340                 /* We have some initial padding bytes. */
3341                 /* XXX - use the data offset here instead? */
3342                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3343                         TRUE);
3344                 offset += bc-datalen;
3345                 bc = datalen;
3346         }
3347         tvblen = tvb_length_remaining(tvb, offset);
3348         if(bc>tvblen){
3349                 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);
3350                 offset += tvblen;
3351         } else {
3352                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3353                 offset += bc;
3354         }
3355         return offset;
3356 }
3357
3358 static int
3359 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3360     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
3361 {
3362         int tvblen;
3363         tvbuff_t *dcerpc_tvb;
3364
3365         if(bc>datalen){
3366                 /* We have some initial padding bytes. */
3367                 /* XXX - use the data offset here instead? */
3368                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3369                         TRUE);
3370                 offset += bc-datalen;
3371                 bc = datalen;
3372         }
3373         tvblen = tvb_length_remaining(tvb, offset);
3374         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
3375         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
3376         if(bc>tvblen)
3377                 offset += tvblen;
3378         else
3379                 offset += bc;
3380         return offset;
3381 }
3382
3383 /*
3384  * transporting DCERPC over SMB seems to be implemented in various
3385  * ways. We might just assume it can be done by an almost random
3386  * mix of Trans/Read/Write calls
3387  *
3388  * if we suspect dcerpc, just send them all down to packet-smb-pipe.c
3389  * and let him sort them out
3390  */
3391 static int
3392 dissect_file_data_maybe_dcerpc(tvbuff_t *tvb, packet_info *pinfo,
3393     proto_tree *tree, proto_tree *top_tree, int offset, guint16 bc,
3394     guint16 datalen, guint32 ofs, guint16 fid)
3395 {
3396         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3397
3398         if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
3399                 /* dcerpc call */
3400                 return dissect_file_data_dcerpc(tvb, pinfo, tree,
3401                     top_tree, offset, bc, datalen, fid);
3402         } else {
3403                 /* ordinary file data */
3404                 return dissect_file_data(tvb, tree, offset, bc, datalen);
3405         }
3406 }
3407
3408 static int
3409 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3410 {
3411         guint16 cnt=0, bc;
3412         guint8 wc;
3413         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3414         int fid=0;
3415
3416         WORD_COUNT;
3417
3418         /* read count */
3419         cnt = tvb_get_letohs(tvb, offset);
3420         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3421         offset += 2;
3422
3423         /* 8 reserved bytes */
3424         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3425         offset += 8;
3426
3427         /* If we have seen the request, then print which FID this refers to */
3428         /* first check if we have seen the request */
3429         if(si->sip != NULL && si->sip->frame_req>0){
3430                 fid=(int)si->sip->extra_info;
3431                 add_fid(tvb, pinfo, tree, 0, 0, fid);
3432         }
3433
3434         BYTE_COUNT;
3435
3436         /* buffer format */
3437         CHECK_BYTE_COUNT(1);
3438         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3439         COUNT_BYTES(1);
3440
3441         /* data len */
3442         CHECK_BYTE_COUNT(2);
3443         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3444         COUNT_BYTES(2);
3445
3446         /* file data, might be DCERPC on a pipe */
3447         if(bc){
3448                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3449                     top_tree, offset, bc, bc, 0, fid);
3450                 bc = 0;
3451         }
3452
3453         END_OF_SMB
3454
3455         return offset;
3456 }
3457
3458 static int
3459 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3460 {
3461         guint16 cnt, bc;
3462         guint8 wc;
3463
3464         WORD_COUNT;
3465
3466         /* read count */
3467         cnt = tvb_get_letohs(tvb, offset);
3468         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3469         offset += 2;
3470
3471         /* 8 reserved bytes */
3472         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3473         offset += 8;
3474
3475         BYTE_COUNT;
3476
3477         /* buffer format */
3478         CHECK_BYTE_COUNT(1);
3479         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3480         COUNT_BYTES(1);
3481
3482         /* data len */
3483         CHECK_BYTE_COUNT(2);
3484         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3485         COUNT_BYTES(2);
3486
3487         END_OF_SMB
3488
3489         return offset;
3490 }
3491
3492
3493 static int
3494 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3495 {
3496         guint32 ofs=0;
3497         guint16 cnt=0, bc, fid=0;
3498         guint8 wc;
3499
3500         WORD_COUNT;
3501
3502         /* fid */
3503         fid = tvb_get_letohs(tvb, offset);
3504         add_fid(tvb, pinfo, tree, offset, 2, fid);
3505         offset += 2;
3506
3507         /* write count */
3508         cnt = tvb_get_letohs(tvb, offset);
3509         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3510         offset += 2;
3511
3512         /* offset */
3513         ofs = tvb_get_letohl(tvb, offset);
3514         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3515         offset += 4;
3516
3517         if (check_col(pinfo->cinfo, COL_INFO))
3518                 col_append_fstr(pinfo->cinfo, COL_INFO,
3519                                 ", %u byte%s at offset %u", cnt,
3520                                 (cnt == 1) ? "" : "s", ofs);
3521
3522         /* remaining */
3523         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3524         offset += 2;
3525
3526         BYTE_COUNT;
3527
3528         /* buffer format */
3529         CHECK_BYTE_COUNT(1);
3530         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3531         COUNT_BYTES(1);
3532
3533         /* data len */
3534         CHECK_BYTE_COUNT(2);
3535         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3536         COUNT_BYTES(2);
3537
3538         /* file data, might be DCERPC on a pipe */
3539         if (bc != 0) {
3540                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3541                     top_tree, offset, bc, bc, ofs, fid);
3542                 bc = 0;
3543         }
3544
3545         END_OF_SMB
3546
3547         return offset;
3548 }
3549
3550 static int
3551 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3552 {
3553         guint8 wc;
3554         guint16 bc, cnt;
3555
3556         WORD_COUNT;
3557
3558         /* write count */
3559         cnt = tvb_get_letohs(tvb, offset);
3560         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3561         offset += 2;
3562
3563         if (check_col(pinfo->cinfo, COL_INFO))
3564                 col_append_fstr(pinfo->cinfo, COL_INFO,
3565                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
3566
3567         BYTE_COUNT;
3568
3569         END_OF_SMB
3570
3571         return offset;
3572 }
3573
3574 static int
3575 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3576 {
3577         guint8 wc;
3578         guint16 bc, fid;
3579
3580         WORD_COUNT;
3581
3582         /* fid */
3583         fid = tvb_get_letohs(tvb, offset);
3584         add_fid(tvb, pinfo, tree, offset, 2, fid);
3585         offset += 2;
3586
3587         /* lock count */
3588         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3589         offset += 4;
3590
3591         /* offset */
3592         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3593         offset += 4;
3594
3595         BYTE_COUNT;
3596
3597         END_OF_SMB
3598
3599         return offset;
3600 }
3601
3602 static int
3603 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3604 {
3605         smb_info_t *si = pinfo->private_data;
3606         int fn_len;
3607         const char *fn;
3608         guint8 wc;
3609         guint16 bc;
3610
3611         WORD_COUNT;
3612
3613         /* 2 reserved bytes */
3614         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3615         offset += 2;
3616
3617         /* Creation time */
3618         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3619
3620         BYTE_COUNT;
3621
3622         /* buffer format */
3623         CHECK_BYTE_COUNT(1);
3624         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3625         COUNT_BYTES(1);
3626
3627         /* directory name */
3628         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3629                 FALSE, FALSE, &bc);
3630         if (fn == NULL)
3631                 goto endofcommand;
3632         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3633                 fn);
3634         COUNT_BYTES(fn_len);
3635
3636         if (check_col(pinfo->cinfo, COL_INFO)) {
3637                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3638         }
3639
3640         END_OF_SMB
3641
3642         return offset;
3643 }
3644
3645 static int
3646 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3647 {
3648         smb_info_t *si = pinfo->private_data;
3649         int fn_len;
3650         const char *fn;
3651         guint8 wc;
3652         guint16 bc, fid;
3653
3654         WORD_COUNT;
3655
3656         /* fid */
3657         fid = tvb_get_letohs(tvb, offset);
3658         add_fid(tvb, pinfo, tree, offset, 2, fid);
3659         offset += 2;
3660
3661         BYTE_COUNT;
3662
3663         /* buffer format */
3664         CHECK_BYTE_COUNT(1);
3665         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3666         COUNT_BYTES(1);
3667
3668         /* file name */
3669         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3670                 FALSE, FALSE, &bc);
3671         if (fn == NULL)
3672                 goto endofcommand;
3673         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3674                 fn);
3675         COUNT_BYTES(fn_len);
3676
3677         END_OF_SMB
3678
3679         return offset;
3680 }
3681
3682 static const value_string seek_mode_vals[] = {
3683         {0,     "From Start Of File"},
3684         {1,     "From Current Position"},
3685         {2,     "From End Of File"},
3686         {0,     NULL}
3687 };
3688
3689 static int
3690 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3691 {
3692         guint8 wc;
3693         guint16 bc, fid;
3694
3695         WORD_COUNT;
3696
3697         /* fid */
3698         fid = tvb_get_letohs(tvb, offset);
3699         add_fid(tvb, pinfo, tree, offset, 2, fid);
3700         offset += 2;
3701
3702         /* Seek Mode */
3703         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3704         offset += 2;
3705
3706         /* offset */
3707         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3708         offset += 4;
3709
3710         BYTE_COUNT;
3711
3712         END_OF_SMB
3713
3714         return offset;
3715 }
3716
3717 static int
3718 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3719 {
3720         guint8 wc;
3721         guint16 bc;
3722
3723         WORD_COUNT;
3724
3725         /* offset */
3726         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3727         offset += 4;
3728
3729         BYTE_COUNT;
3730
3731         END_OF_SMB
3732
3733         return offset;
3734 }
3735
3736 static int
3737 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3738 {
3739         guint8 wc;
3740         guint16 bc, fid;
3741
3742         WORD_COUNT;
3743
3744         /* fid */
3745         fid = tvb_get_letohs(tvb, offset);
3746         add_fid(tvb, pinfo, tree, offset, 2, fid);
3747         offset += 2;
3748
3749         /* create time */
3750         offset = dissect_smb_datetime(tvb, tree, offset,
3751                 hf_smb_create_time,
3752                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3753
3754         /* access time */
3755         offset = dissect_smb_datetime(tvb, tree, offset,
3756                 hf_smb_access_time,
3757                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3758
3759         /* last write time */
3760         offset = dissect_smb_datetime(tvb, tree, offset,
3761                 hf_smb_last_write_time,
3762                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3763
3764         BYTE_COUNT;
3765
3766         END_OF_SMB
3767
3768         return offset;
3769 }
3770
3771 static int
3772 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3773 {
3774         guint8 wc;
3775         guint16 bc;
3776
3777         WORD_COUNT;
3778
3779         /* create time */
3780         offset = dissect_smb_datetime(tvb, tree, offset,
3781                 hf_smb_create_time,
3782                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3783
3784         /* access time */
3785         offset = dissect_smb_datetime(tvb, tree, offset,
3786                 hf_smb_access_time,
3787                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3788
3789         /* last write time */
3790         offset = dissect_smb_datetime(tvb, tree, offset,
3791                 hf_smb_last_write_time,
3792                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3793
3794         /* data size */
3795         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3796         offset += 4;
3797
3798         /* allocation size */
3799         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3800         offset += 4;
3801
3802         /* File Attributes */
3803         offset = dissect_file_attributes(tvb, tree, offset, 2);
3804
3805         BYTE_COUNT;
3806
3807         END_OF_SMB
3808
3809         return offset;
3810 }
3811
3812 static int
3813 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3814 {
3815         guint8 wc;
3816         guint16 cnt=0;
3817         guint16 bc, fid;
3818
3819         WORD_COUNT;
3820
3821         /* fid */
3822         fid = tvb_get_letohs(tvb, offset);
3823         add_fid(tvb, pinfo, tree, offset, 2, fid);
3824         offset += 2;
3825
3826         /* write count */
3827         cnt = tvb_get_letohs(tvb, offset);
3828         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3829         offset += 2;
3830
3831         /* offset */
3832         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3833         offset += 4;
3834
3835         /* last write time */
3836         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3837
3838         if(wc==12){
3839                 /* 12 reserved bytes */
3840                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3841                 offset += 12;
3842         }
3843
3844         BYTE_COUNT;
3845
3846         /* 1 pad byte */
3847         CHECK_BYTE_COUNT(1);
3848         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3849         COUNT_BYTES(1);
3850
3851         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
3852         bc = 0; /* XXX */
3853
3854         END_OF_SMB
3855
3856         return offset;
3857 }
3858
3859 static int
3860 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3861 {
3862         guint8 wc;
3863         guint16 bc;
3864
3865         WORD_COUNT;
3866
3867         /* write count */
3868         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3869         offset += 2;
3870
3871         BYTE_COUNT;
3872
3873         END_OF_SMB
3874
3875         return offset;
3876 }
3877
3878 static int
3879 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3880 {
3881         guint8 wc;
3882         guint16 bc, fid;
3883         guint32 to;
3884
3885         WORD_COUNT;
3886
3887         /* fid */
3888         fid = tvb_get_letohs(tvb, offset);
3889         add_fid(tvb, pinfo, tree, offset, 2, fid);
3890         offset += 2;
3891
3892         /* offset */
3893         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3894         offset += 4;
3895
3896         /* max count */
3897         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3898         offset += 2;
3899
3900         /* min count */
3901         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3902         offset += 2;
3903
3904         /* timeout */
3905         to = tvb_get_letohl(tvb, offset);
3906         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3907         offset += 4;
3908
3909         /* 2 reserved bytes */
3910         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3911         offset += 2;
3912
3913         if(wc==10){
3914                 /* high offset */
3915                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3916                 offset += 4;
3917         }
3918
3919         BYTE_COUNT;
3920
3921         END_OF_SMB
3922
3923         return offset;
3924 }
3925
3926 static int
3927 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3928 {
3929         guint8 wc;
3930         guint16 bc;
3931
3932         WORD_COUNT;
3933
3934         /* units */
3935         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3936         offset += 2;
3937
3938         /* bpu */
3939         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3940         offset += 2;
3941
3942         /* block size */
3943         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3944         offset += 2;
3945
3946         /* free units */
3947         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3948         offset += 2;
3949
3950         /* 2 reserved bytes */
3951         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3952         offset += 2;
3953
3954         BYTE_COUNT;
3955
3956         END_OF_SMB
3957
3958         return offset;
3959 }
3960
3961 static int
3962 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3963 {
3964         guint8 wc;
3965         guint16 bc, fid;
3966
3967         WORD_COUNT;
3968
3969         /* fid */
3970         fid = tvb_get_letohs(tvb, offset);
3971         add_fid(tvb, pinfo, tree, offset, 2, fid);
3972         offset += 2;
3973
3974         /* offset */
3975         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3976         offset += 4;
3977
3978         /* max count */
3979         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3980         offset += 2;
3981
3982         /* min count */
3983         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3984         offset += 2;
3985
3986         /* 6 reserved bytes */
3987         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
3988         offset += 6;
3989
3990         BYTE_COUNT;
3991
3992         END_OF_SMB
3993
3994         return offset;
3995 }
3996
3997 static int
3998 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3999 {
4000         guint16 datalen=0, bc;
4001         guint8 wc;
4002
4003         WORD_COUNT;
4004
4005         /* offset */
4006         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4007         offset += 4;
4008
4009         /* count */
4010         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4011         offset += 2;
4012
4013         /* 2 reserved bytes */
4014         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4015         offset += 2;
4016
4017         /* data compaction mode */
4018         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4019         offset += 2;
4020
4021         /* 2 reserved bytes */
4022         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4023         offset += 2;
4024
4025         /* data len */
4026         datalen = tvb_get_letohs(tvb, offset);
4027         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4028         offset += 2;
4029
4030         /* data offset */
4031         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4032         offset += 2;
4033
4034         BYTE_COUNT;
4035
4036         /* file data */
4037         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4038         bc = 0;
4039
4040         END_OF_SMB
4041
4042         return offset;
4043 }
4044
4045
4046 static const true_false_string tfs_write_mode_write_through = {
4047         "WRITE THROUGH requested",
4048         "Write through not requested"
4049 };
4050 static const true_false_string tfs_write_mode_return_remaining = {
4051         "RETURN REMAINING (pipe/dev) requested",
4052         "DON'T return remaining (pipe/dev)"
4053 };
4054 static const true_false_string tfs_write_mode_raw = {
4055         "Use WriteRawNamedPipe (pipe)",
4056         "DON'T use WriteRawNamedPipe (pipe)"
4057 };
4058 static const true_false_string tfs_write_mode_message_start = {
4059         "This is the START of a MESSAGE (pipe)",
4060         "This is NOT the start of a message (pipe)"
4061 };
4062 static const true_false_string tfs_write_mode_connectionless = {
4063         "CONNECTIONLESS mode requested",
4064         "Connectionless mode NOT requested"
4065 };
4066
4067 #define WRITE_MODE_CONNECTIONLESS       0x0080
4068 #define WRITE_MODE_MESSAGE_START        0x0008
4069 #define WRITE_MODE_RAW                  0x0004
4070 #define WRITE_MODE_RETURN_REMAINING     0x0002
4071 #define WRITE_MODE_WRITE_THROUGH        0x0001
4072
4073 static int
4074 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4075 {
4076         guint16 mask;
4077         proto_item *item = NULL;
4078         proto_tree *tree = NULL;
4079
4080         mask = tvb_get_letohs(tvb, offset);
4081
4082         if(parent_tree){
4083                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4084                         "Write Mode: 0x%04x", mask);
4085                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
4086         }
4087
4088         if(bm&WRITE_MODE_CONNECTIONLESS){
4089                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
4090                         tvb, offset, 2, mask);
4091         }
4092         if(bm&WRITE_MODE_MESSAGE_START){
4093                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
4094                         tvb, offset, 2, mask);
4095         }
4096         if(bm&WRITE_MODE_RAW){
4097                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
4098                         tvb, offset, 2, mask);
4099         }
4100         if(bm&WRITE_MODE_RETURN_REMAINING){
4101                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
4102                         tvb, offset, 2, mask);
4103         }
4104         if(bm&WRITE_MODE_WRITE_THROUGH){
4105                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4106                         tvb, offset, 2, mask);
4107         }
4108
4109         offset += 2;
4110         return offset;
4111 }
4112
4113 static int
4114 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4115 {
4116         guint32 to;
4117         guint16 datalen=0, bc, fid;
4118         guint8 wc;
4119
4120         WORD_COUNT;
4121
4122         /* fid */
4123         fid = tvb_get_letohs(tvb, offset);
4124         add_fid(tvb, pinfo, tree, offset, 2, fid);
4125         offset += 2;
4126
4127         /* total data length */
4128         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4129         offset += 2;
4130
4131         /* 2 reserved bytes */
4132         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4133         offset += 2;
4134
4135         /* offset */
4136         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4137         offset += 4;
4138
4139         /* timeout */
4140         to = tvb_get_letohl(tvb, offset);
4141         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4142         offset += 4;
4143
4144         /* mode */
4145         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4146
4147         /* 4 reserved bytes */
4148         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4149         offset += 4;
4150
4151         /* data len */
4152         datalen = tvb_get_letohs(tvb, offset);
4153         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4154         offset += 2;
4155
4156         /* data offset */
4157         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4158         offset += 2;
4159
4160         BYTE_COUNT;
4161
4162         /* file data */
4163         /* XXX - use the data offset to determine where the data starts? */
4164         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4165         bc = 0;
4166
4167         END_OF_SMB
4168
4169         return offset;
4170 }
4171
4172 static int
4173 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4174 {
4175         guint8 wc;
4176         guint16 bc;
4177
4178         WORD_COUNT;
4179
4180         /* remaining */
4181         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4182         offset += 2;
4183
4184         BYTE_COUNT;
4185
4186         END_OF_SMB
4187
4188         return offset;
4189 }
4190
4191 static int
4192 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4193 {
4194         guint32 to;
4195         guint16 datalen=0, bc, fid;
4196         guint8 wc;
4197
4198         WORD_COUNT;
4199
4200         /* fid */
4201         fid = tvb_get_letohs(tvb, offset);
4202         add_fid(tvb, pinfo, tree, offset, 2, fid);
4203         offset += 2;
4204
4205         /* total data length */
4206         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4207         offset += 2;
4208
4209         /* 2 reserved bytes */
4210         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4211         offset += 2;
4212
4213         /* offset */
4214         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4215         offset += 4;
4216
4217         /* timeout */
4218         to = tvb_get_letohl(tvb, offset);
4219         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4220         offset += 4;
4221
4222         /* mode */
4223         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
4224
4225         /* request mask */
4226         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
4227         offset += 4;
4228
4229         /* data len */
4230         datalen = tvb_get_letohs(tvb, offset);
4231         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4232         offset += 2;
4233
4234         /* data offset */
4235         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4236         offset += 2;
4237
4238         BYTE_COUNT;
4239
4240         /* file data */
4241         /* XXX - use the data offset to determine where the data starts? */
4242         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4243         bc = 0;
4244
4245         END_OF_SMB
4246
4247         return offset;
4248 }
4249
4250 static int
4251 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4252 {
4253         guint8 wc;
4254         guint16 bc;
4255
4256         WORD_COUNT;
4257
4258         /* response mask */
4259         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
4260         offset += 4;
4261
4262         BYTE_COUNT;
4263
4264         END_OF_SMB
4265
4266         return offset;
4267 }
4268
4269 static int
4270 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4271 {
4272         guint8 wc;
4273         guint16 bc;
4274
4275         WORD_COUNT;
4276
4277         /* sid */
4278         proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
4279         offset += 2;
4280
4281         BYTE_COUNT;
4282
4283         END_OF_SMB
4284
4285         return offset;
4286 }
4287
4288 static int
4289 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
4290     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4291     gboolean has_find_id)
4292 {
4293         proto_item *item = NULL;
4294         proto_tree *tree = NULL;
4295         smb_info_t *si = pinfo->private_data;
4296         int fn_len;
4297         const char *fn;
4298         char fname[11+1];
4299
4300         if(parent_tree){
4301                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
4302                         "Resume Key");
4303                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
4304         }
4305
4306         /* reserved byte */
4307         CHECK_BYTE_COUNT_SUBR(1);
4308         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4309         COUNT_BYTES_SUBR(1);
4310
4311         /* file name */
4312         fn_len = 11;
4313         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4314                 TRUE, TRUE, bcp);
4315         CHECK_STRING_SUBR(fn);
4316         /* ensure that it's null-terminated */
4317         strncpy(fname, fn, 11);
4318         fname[11] = '\0';
4319         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
4320                 fname);
4321         COUNT_BYTES_SUBR(fn_len);
4322
4323         if (has_find_id) {
4324                 CHECK_BYTE_COUNT_SUBR(1);
4325                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
4326                 COUNT_BYTES_SUBR(1);
4327
4328                 /* server cookie */
4329                 CHECK_BYTE_COUNT_SUBR(4);
4330                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
4331                 COUNT_BYTES_SUBR(4);
4332         } else {
4333                 /* server cookie */
4334                 CHECK_BYTE_COUNT_SUBR(5);
4335                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
4336                 COUNT_BYTES_SUBR(5);
4337         }
4338
4339         /* client cookie */
4340         CHECK_BYTE_COUNT_SUBR(4);
4341         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
4342         COUNT_BYTES_SUBR(4);
4343
4344         *trunc = FALSE;
4345         return offset;
4346 }
4347
4348 static int
4349 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
4350     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4351     gboolean has_find_id)
4352 {
4353         proto_item *item = NULL;
4354         proto_tree *tree = NULL;
4355         smb_info_t *si = pinfo->private_data;
4356         int fn_len;
4357         const char *fn;
4358         char fname[13+1];
4359
4360         if(parent_tree){
4361                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
4362                         "Directory Information");
4363                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
4364         }
4365
4366         /* resume key */
4367         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
4368             trunc, has_find_id);
4369         if (*trunc)
4370                 return offset;
4371
4372         /* File Attributes */
4373         CHECK_BYTE_COUNT_SUBR(1);
4374         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
4375         *bcp -= 1;
4376
4377         /* last write time */
4378         CHECK_BYTE_COUNT_SUBR(4);
4379         offset = dissect_smb_datetime(tvb, tree, offset,
4380                 hf_smb_last_write_time,
4381                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
4382                 TRUE);
4383         *bcp -= 4;
4384
4385         /* File Size */
4386         CHECK_BYTE_COUNT_SUBR(4);
4387         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4388         COUNT_BYTES_SUBR(4);
4389
4390         /* file name */
4391         fn_len = 13;
4392         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4393                 TRUE, TRUE, bcp);
4394         CHECK_STRING_SUBR(fn);
4395         /* ensure that it's null-terminated */
4396         strncpy(fname, fn, 13);
4397         fname[13] = '\0';
4398         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4399                 fname);
4400         COUNT_BYTES_SUBR(fn_len);
4401
4402         *trunc = FALSE;
4403         return offset;
4404 }
4405
4406
4407 static int
4408 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
4409     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4410     gboolean has_find_id)
4411 {
4412         smb_info_t *si = pinfo->private_data;
4413         int fn_len;
4414         const char *fn;
4415         guint16 rkl;
4416         guint8 wc;
4417         guint16 bc;
4418         gboolean trunc;
4419
4420         WORD_COUNT;
4421
4422         /* max count */
4423         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4424         offset += 2;
4425
4426         /* Search Attributes */
4427         offset = dissect_search_attributes(tvb, tree, offset);
4428
4429         BYTE_COUNT;
4430
4431         /* buffer format */
4432         CHECK_BYTE_COUNT(1);
4433         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4434         COUNT_BYTES(1);
4435
4436         /* file name */
4437         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4438                 TRUE, FALSE, &bc);
4439         if (fn == NULL)
4440                 goto endofcommand;
4441         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4442                 fn);
4443         COUNT_BYTES(fn_len);
4444
4445         if (check_col(pinfo->cinfo, COL_INFO)) {
4446                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", fn);
4447         }
4448
4449         /* buffer format */
4450         CHECK_BYTE_COUNT(1);
4451         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4452         COUNT_BYTES(1);
4453
4454         /* resume key length */
4455         CHECK_BYTE_COUNT(2);
4456         rkl = tvb_get_letohs(tvb, offset);
4457         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
4458         COUNT_BYTES(2);
4459
4460         /* resume key */
4461         if(rkl){
4462                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
4463                     &bc, &trunc, has_find_id);
4464                 if (trunc)
4465                         goto endofcommand;
4466         }
4467
4468         END_OF_SMB
4469
4470         return offset;
4471 }
4472
4473 static int
4474 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4475     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4476 {
4477         return dissect_search_find_request(tvb, pinfo, tree, offset,
4478             smb_tree, FALSE);
4479 }
4480
4481 static int
4482 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4483     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4484 {
4485         return dissect_search_find_request(tvb, pinfo, tree, offset,
4486             smb_tree, TRUE);
4487 }
4488
4489 static int
4490 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4491     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4492 {
4493         return dissect_search_find_request(tvb, pinfo, tree, offset,
4494             smb_tree, TRUE);
4495 }
4496
4497 static int
4498 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4499     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4500     gboolean has_find_id)
4501 {
4502         guint16 count=0;
4503         guint8 wc;
4504         guint16 bc;
4505         gboolean trunc;
4506
4507         WORD_COUNT;
4508
4509         /* count */
4510         count = tvb_get_letohs(tvb, offset);
4511         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
4512         offset += 2;
4513
4514         BYTE_COUNT;
4515
4516         /* buffer format */
4517         CHECK_BYTE_COUNT(1);
4518         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4519         COUNT_BYTES(1);
4520
4521         /* data len */
4522         CHECK_BYTE_COUNT(2);
4523         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4524         COUNT_BYTES(2);
4525
4526         while(count--){
4527                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
4528                     &bc, &trunc, has_find_id);
4529                 if (trunc)
4530                         goto endofcommand;
4531         }
4532
4533         END_OF_SMB
4534
4535         return offset;
4536 }
4537
4538 static int
4539 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4540 {
4541         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4542             FALSE);
4543 }
4544
4545 static int
4546 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4547 {
4548         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4549             TRUE);
4550 }
4551
4552 static int
4553 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4554     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4555 {
4556         guint8 wc;
4557         guint16 bc;
4558         guint16 data_len;
4559
4560         WORD_COUNT;
4561
4562         /* reserved */
4563         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4564         offset += 2;
4565
4566         BYTE_COUNT;
4567
4568         /* buffer format */
4569         CHECK_BYTE_COUNT(1);
4570         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4571         COUNT_BYTES(1);
4572
4573         /* data len */
4574         CHECK_BYTE_COUNT(2);
4575         data_len = tvb_get_ntohs(tvb, offset);
4576         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
4577         COUNT_BYTES(2);
4578
4579         if (data_len != 0) {
4580                 CHECK_BYTE_COUNT(data_len);
4581                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
4582                     data_len, TRUE);
4583                 COUNT_BYTES(data_len);
4584         }
4585
4586         END_OF_SMB
4587
4588         return offset;
4589 }
4590
4591 static const value_string locking_ol_vals[] = {
4592         {0,     "Client is not holding oplock on this file"},
4593         {1,     "Level 2 oplock currently held by client"},
4594         {0, NULL}
4595 };
4596
4597 static const true_false_string tfs_lock_type_large = {
4598         "Large file locking format requested",
4599         "Large file locking format not requested"
4600 };
4601 static const true_false_string tfs_lock_type_cancel = {
4602         "Cancel outstanding lock request",
4603         "Don't cancel outstanding lock request"
4604 };
4605 static const true_false_string tfs_lock_type_change = {
4606         "Change lock type",
4607         "Don't change lock type"
4608 };
4609 static const true_false_string tfs_lock_type_oplock = {
4610         "This is an oplock break notification/response",
4611         "This is not an oplock break notification/response"
4612 };
4613 static const true_false_string tfs_lock_type_shared = {
4614         "This is a shared lock",
4615         "This is an exclusive lock"
4616 };
4617 static int
4618 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4619 {
4620         guint8  wc, cmd=0xff, lt=0;
4621         guint16 andxoffset=0, un=0, ln=0, bc, fid;
4622         guint32 to;
4623         proto_item *litem = NULL;
4624         proto_tree *ltree = NULL;
4625         proto_item *it = NULL;
4626         proto_tree *tr = NULL;
4627         int old_offset = offset;
4628
4629         WORD_COUNT;
4630
4631         /* next smb command */
4632         cmd = tvb_get_guint8(tvb, offset);
4633         if(cmd!=0xff){
4634                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4635         } else {
4636                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4637         }
4638         offset += 1;
4639
4640         /* reserved byte */
4641         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4642         offset += 1;
4643
4644         /* andxoffset */
4645         andxoffset = tvb_get_letohs(tvb, offset);
4646         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4647         offset += 2;
4648
4649         /* fid */
4650         fid = tvb_get_letohs(tvb, offset);
4651         add_fid(tvb, pinfo, tree, offset, 2, fid);
4652         offset += 2;
4653
4654         /* lock type */
4655         lt = tvb_get_guint8(tvb, offset);
4656         if(tree){
4657                 litem = proto_tree_add_text(tree, tvb, offset, 1,
4658                         "Lock Type: 0x%02x", lt);
4659                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
4660         }
4661         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
4662                 tvb, offset, 1, lt);
4663         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
4664                 tvb, offset, 1, lt);
4665         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
4666                 tvb, offset, 1, lt);
4667         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
4668                 tvb, offset, 1, lt);
4669         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
4670                 tvb, offset, 1, lt);
4671         offset += 1;
4672
4673         /* oplock level */
4674         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
4675         offset += 1;
4676
4677         /* timeout */
4678         to = tvb_get_letohl(tvb, offset);
4679         if (to == 0)
4680                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
4681         else if (to == 0xffffffff)
4682                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
4683         else
4684                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4685         offset += 4;
4686
4687         /* number of unlocks */
4688         un = tvb_get_letohs(tvb, offset);
4689         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
4690         offset += 2;
4691
4692         /* number of locks */
4693         ln = tvb_get_letohs(tvb, offset);
4694         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
4695         offset += 2;
4696
4697         BYTE_COUNT;
4698
4699         /* unlocks */
4700         if(un){
4701                 old_offset = offset;
4702
4703                 it = proto_tree_add_text(tree, tvb, offset, -1,
4704                         "Unlocks");
4705                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
4706                 while(un--){
4707                         proto_item *litem = NULL;
4708                         proto_tree *ltree = NULL;
4709                         if(lt&0x10){
4710                                 /* large lock format */
4711                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4712                                         "Unlock");
4713                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4714
4715                                 /* PID */
4716                                 CHECK_BYTE_COUNT(2);
4717                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4718                                 COUNT_BYTES(2);
4719
4720                                 /* 2 reserved bytes */
4721                                 CHECK_BYTE_COUNT(2);
4722                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4723                                 COUNT_BYTES(2);
4724
4725                                 /* offset */
4726                                 CHECK_BYTE_COUNT(8);
4727                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4728                                 COUNT_BYTES(8);
4729
4730                                 /* length */
4731                                 CHECK_BYTE_COUNT(8);
4732                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4733                                 COUNT_BYTES(8);
4734                         } else {
4735                                 /* normal lock format */
4736                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4737                                         "Unlock");
4738                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4739
4740                                 /* PID */
4741                                 CHECK_BYTE_COUNT(2);
4742                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4743                                 COUNT_BYTES(2);
4744
4745                                 /* offset */
4746                                 CHECK_BYTE_COUNT(4);
4747                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4748                                 COUNT_BYTES(4);
4749
4750                                 /* lock count */
4751                                 CHECK_BYTE_COUNT(4);
4752                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4753                                 COUNT_BYTES(4);
4754                         }
4755                 }
4756                 proto_item_set_len(it, offset-old_offset);
4757                 it = NULL;
4758         }
4759
4760         /* locks */
4761         if(ln){
4762                 old_offset = offset;
4763
4764                 it = proto_tree_add_text(tree, tvb, offset, -1,
4765                         "Locks");
4766                 tr = proto_item_add_subtree(it, ett_smb_locks);
4767                 while(ln--){
4768                         proto_item *litem = NULL;
4769                         proto_tree *ltree = NULL;
4770                         if(lt&0x10){
4771                                 /* large lock format */
4772                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4773                                         "Lock");
4774                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
4775
4776                                 /* PID */
4777                                 CHECK_BYTE_COUNT(2);
4778                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4779                                 COUNT_BYTES(2);
4780
4781                                 /* 2 reserved bytes */
4782                                 CHECK_BYTE_COUNT(2);
4783                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4784                                 COUNT_BYTES(2);
4785
4786                                 /* offset */
4787                                 CHECK_BYTE_COUNT(8);
4788                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4789                                 COUNT_BYTES(8);
4790
4791                                 /* length */
4792                                 CHECK_BYTE_COUNT(8);
4793                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4794                                 COUNT_BYTES(8);
4795                         } else {
4796                                 /* normal lock format */
4797                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4798                                         "Unlock");
4799                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4800
4801                                 /* PID */
4802                                 CHECK_BYTE_COUNT(2);
4803                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4804                                 COUNT_BYTES(2);
4805
4806                                 /* offset */
4807                                 CHECK_BYTE_COUNT(4);
4808                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4809                                 COUNT_BYTES(4);
4810
4811                                 /* lock count */
4812                                 CHECK_BYTE_COUNT(4);
4813                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4814                                 COUNT_BYTES(4);
4815                         }
4816                 }
4817                 proto_item_set_len(it, offset-old_offset);
4818                 it = NULL;
4819         }
4820
4821         END_OF_SMB
4822
4823         if (it != NULL) {
4824                 /*
4825                  * We ran out of byte count in the middle of dissecting
4826                  * the locks or the unlocks; set the site of the item
4827                  * we were dissecting.
4828                  */
4829                 proto_item_set_len(it, offset-old_offset);
4830         }
4831
4832         /* call AndXCommand (if there are any) */
4833         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4834
4835         return offset;
4836 }
4837
4838 static int
4839 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4840 {
4841         guint8  wc, cmd=0xff;
4842         guint16 andxoffset=0;
4843         guint16 bc;
4844
4845         WORD_COUNT;
4846
4847         /* next smb command */
4848         cmd = tvb_get_guint8(tvb, offset);
4849         if(cmd!=0xff){
4850                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4851         } else {
4852                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4853         }
4854         offset += 1;
4855
4856         /* reserved byte */
4857         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4858         offset += 1;
4859
4860         /* andxoffset */
4861         andxoffset = tvb_get_letohs(tvb, offset);
4862         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4863         offset += 2;
4864
4865         BYTE_COUNT;
4866
4867         END_OF_SMB
4868
4869         /* call AndXCommand (if there are any) */
4870         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4871
4872         return offset;
4873 }
4874
4875
4876 static const value_string oa_open_vals[] = {
4877         { 0,            "No action taken?"},
4878         { 1,            "The file existed and was opened"},
4879         { 2,            "The file did not exist but was created"},
4880         { 3,            "The file existed and was truncated"},
4881         { 0x8001,       "The file existed and was opened, and an OpLock was granted"}, 
4882         { 0x8002,       "The file did not exist but was created, and an OpLock was granted"},
4883         { 0x8002,       "The file existed and was truncated, and an OpLock was granted"},
4884         {0,     NULL}
4885 };
4886 static const true_false_string tfs_oa_lock = {
4887         "File is currently opened only by this user",
4888         "File is opened by another user (or mode not supported by server)"
4889 };
4890 static int
4891 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
4892 {
4893         guint16 mask;
4894         proto_item *item = NULL;
4895         proto_tree *tree = NULL;
4896
4897         mask = tvb_get_letohs(tvb, offset);
4898
4899         if(parent_tree){
4900                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4901                         "Action: 0x%04x", mask);
4902                 tree = proto_item_add_subtree(item, ett_smb_open_action);
4903         }
4904
4905         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
4906                 tvb, offset, 2, mask);
4907         proto_tree_add_uint(tree, hf_smb_open_action_open,
4908                 tvb, offset, 2, mask);
4909
4910         offset += 2;
4911
4912         return offset;
4913 }
4914
4915 static const true_false_string tfs_open_flags_add_info = {
4916         "Additional information requested",
4917         "Additional information not requested"
4918 };
4919 static const true_false_string tfs_open_flags_ex_oplock = {
4920         "Exclusive oplock requested",
4921         "Exclusive oplock not requested"
4922 };
4923 static const true_false_string tfs_open_flags_batch_oplock = {
4924         "Batch oplock requested",
4925         "Batch oplock not requested"
4926 };
4927 static const true_false_string tfs_open_flags_ealen = {
4928         "Total length of EAs requested",
4929         "Total length of EAs not requested"
4930 };
4931 static int
4932 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4933 {
4934         guint16 mask;
4935         proto_item *item = NULL;
4936         proto_tree *tree = NULL;
4937
4938         mask = tvb_get_letohs(tvb, offset);
4939
4940         if(parent_tree){
4941                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4942                         "Flags: 0x%04x", mask);
4943                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
4944         }
4945
4946         if(bm&0x0001){
4947                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
4948                         tvb, offset, 2, mask);
4949         }
4950         if(bm&0x0002){
4951                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
4952                         tvb, offset, 2, mask);
4953         }
4954         if(bm&0x0004){
4955                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
4956                         tvb, offset, 2, mask);
4957         }
4958         if(bm&0x0008){
4959                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
4960                         tvb, offset, 2, mask);
4961         }
4962
4963         offset += 2;
4964
4965         return offset;
4966 }
4967
4968 static const value_string filetype_vals[] = {
4969         { 0,            "Disk file or directory"},
4970         { 1,            "Named pipe in byte mode"},
4971         { 2,            "Named pipe in message mode"},
4972         { 3,            "Spooled printer"},
4973         {0, NULL}
4974 };
4975 static int
4976 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4977 {
4978         guint8  wc, cmd=0xff;
4979         guint16 andxoffset=0, bc;
4980         smb_info_t *si = pinfo->private_data;
4981         int fn_len;
4982         const char *fn;
4983
4984         WORD_COUNT;
4985
4986         /* next smb command */
4987         cmd = tvb_get_guint8(tvb, offset);
4988         if(cmd!=0xff){
4989                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4990         } else {
4991                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4992         }
4993         offset += 1;
4994
4995         /* reserved byte */
4996         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4997         offset += 1;
4998
4999         /* andxoffset */
5000         andxoffset = tvb_get_letohs(tvb, offset);
5001         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5002         offset += 2;
5003
5004         /* open flags */
5005         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
5006
5007         /* desired access */
5008         offset = dissect_access(tvb, tree, offset, "Desired");
5009
5010         /* Search Attributes */
5011         offset = dissect_search_attributes(tvb, tree, offset);
5012
5013         /* File Attributes */
5014         offset = dissect_file_attributes(tvb, tree, offset, 2);
5015
5016         /* creation time */
5017         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
5018
5019         /* open function */
5020         offset = dissect_open_function(tvb, tree, offset);
5021
5022         /* allocation size */
5023         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
5024         offset += 4;
5025
5026         /* 8 reserved bytes */
5027         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
5028         offset += 8;
5029
5030         BYTE_COUNT;
5031
5032         /* file name */
5033         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5034                 FALSE, FALSE, &bc);
5035         if (fn == NULL)
5036                 goto endofcommand;
5037         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5038                 fn);
5039         COUNT_BYTES(fn_len);
5040
5041         if (check_col(pinfo->cinfo, COL_INFO)) {
5042                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
5043         }
5044
5045         END_OF_SMB
5046
5047         /* call AndXCommand (if there are any) */
5048         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5049
5050         return offset;
5051 }
5052
5053 static const true_false_string tfs_ipc_state_nonblocking = {
5054         "Reads/writes return immediately if no data available",
5055         "Reads/writes block if no data available"
5056 };
5057 static const value_string ipc_state_endpoint_vals[] = {
5058         { 0,            "Consumer end of pipe"},
5059         { 1,            "Server end of pipe"},
5060         {0,     NULL}
5061 };
5062 static const value_string ipc_state_pipe_type_vals[] = {
5063         { 0,            "Byte stream pipe"},
5064         { 1,            "Message pipe"},
5065         {0,     NULL}
5066 };
5067 static const value_string ipc_state_read_mode_vals[] = {
5068         { 0,            "Read pipe as a byte stream"},
5069         { 1,            "Read messages from pipe"},
5070         {0,     NULL}
5071 };
5072
5073 int
5074 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
5075     gboolean setstate)
5076 {
5077         guint16 mask;
5078         proto_item *item = NULL;
5079         proto_tree *tree = NULL;
5080
5081         mask = tvb_get_letohs(tvb, offset);
5082
5083         if(parent_tree){
5084                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5085                         "IPC State: 0x%04x", mask);
5086                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
5087         }
5088
5089         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
5090                 tvb, offset, 2, mask);
5091         if (!setstate) {
5092                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
5093                         tvb, offset, 2, mask);
5094                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
5095                         tvb, offset, 2, mask);
5096         }
5097         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
5098                 tvb, offset, 2, mask);
5099         if (!setstate) {
5100                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
5101                         tvb, offset, 2, mask);
5102         }
5103
5104         offset += 2;
5105
5106         return offset;
5107 }
5108
5109 static int
5110 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5111 {
5112         guint8  wc, cmd=0xff;
5113         guint16 andxoffset=0, bc;
5114         guint16 fid;
5115
5116         WORD_COUNT;
5117
5118         /* next smb command */
5119         cmd = tvb_get_guint8(tvb, offset);
5120         if(cmd!=0xff){
5121                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5122         } else {
5123                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5124         }
5125         offset += 1;
5126
5127         /* reserved byte */
5128         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5129         offset += 1;
5130
5131         /* andxoffset */
5132         andxoffset = tvb_get_letohs(tvb, offset);
5133         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5134         offset += 2;
5135
5136         /* fid */
5137         fid = tvb_get_letohs(tvb, offset);
5138         add_fid(tvb, pinfo, tree, offset, 2, fid);
5139         offset += 2;
5140
5141         /* File Attributes */
5142         offset = dissect_file_attributes(tvb, tree, offset, 2);
5143
5144         /* last write time */
5145         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
5146
5147         /* File Size */
5148         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5149         offset += 4;
5150
5151         /* granted access */
5152         offset = dissect_access(tvb, tree, offset, "Granted");
5153
5154         /* File Type */
5155         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
5156         offset += 2;
5157
5158         /* IPC State */
5159         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
5160
5161         /* open_action */
5162         offset = dissect_open_action(tvb, tree, offset);
5163
5164         /* server fid */
5165         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
5166         offset += 4;
5167
5168         /* 2 reserved bytes */
5169         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5170         offset += 2;
5171
5172         BYTE_COUNT;
5173
5174         END_OF_SMB
5175
5176         /* call AndXCommand (if there are any) */
5177         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5178
5179         return offset;
5180 }
5181
5182 static int
5183 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5184 {
5185         guint8  wc, cmd=0xff;
5186         guint16 andxoffset=0, bc, maxcnt = 0;
5187         guint32 ofs = 0;
5188         smb_info_t *si;
5189         unsigned int fid;
5190
5191         WORD_COUNT;
5192
5193         /* next smb command */
5194         cmd = tvb_get_guint8(tvb, offset);
5195         if(cmd!=0xff){
5196                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5197         } else {
5198                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5199         }
5200         offset += 1;
5201
5202         /* reserved byte */
5203         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5204         offset += 1;
5205
5206         /* andxoffset */
5207         andxoffset = tvb_get_letohs(tvb, offset);
5208         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5209         offset += 2;
5210
5211         /* fid */
5212         fid = tvb_get_letohs(tvb, offset);
5213         add_fid(tvb, pinfo, tree, offset, 2, fid);
5214         offset += 2;
5215         if (!pinfo->fd->flags.visited) {
5216                 /* remember the FID for the processing of the response */
5217                 si = (smb_info_t *)pinfo->private_data;
5218                 si->sip->extra_info=(void *)fid;
5219         }
5220
5221         /* offset */
5222         ofs = tvb_get_letohl(tvb, offset);
5223         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5224         offset += 4;
5225
5226         /* max count */
5227         maxcnt = tvb_get_letohs(tvb, offset);
5228         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
5229         offset += 2;
5230
5231         if (check_col(pinfo->cinfo, COL_INFO))
5232                 col_append_fstr(pinfo->cinfo, COL_INFO,
5233                                 ", %u byte%s at offset %u", maxcnt,
5234                                 (maxcnt == 1) ? "" : "s", ofs);
5235
5236         /* min count */
5237         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
5238         offset += 2;
5239
5240         /* XXX - max count high */
5241         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5242         offset += 4;
5243
5244         /* remaining */
5245         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5246         offset += 2;
5247
5248         if(wc==12){
5249                 /* high offset */
5250                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5251                 offset += 4;
5252         }
5253
5254         BYTE_COUNT;
5255
5256         END_OF_SMB
5257
5258         /* call AndXCommand (if there are any) */
5259         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5260
5261         return offset;
5262 }
5263
5264 static int
5265 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5266 {
5267         guint8  wc, cmd=0xff;
5268         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
5269         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5270         int fid=0;
5271
5272         WORD_COUNT;
5273
5274         /* next smb command */
5275         cmd = tvb_get_guint8(tvb, offset);
5276         if(cmd!=0xff){
5277                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5278         } else {
5279                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5280         }
5281         offset += 1;
5282
5283         /* reserved byte */
5284         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5285         offset += 1;
5286
5287         /* andxoffset */
5288         andxoffset = tvb_get_letohs(tvb, offset);
5289         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5290         offset += 2;
5291
5292         /* If we have seen the request, then print which FID this refers to */
5293         /* first check if we have seen the request */
5294         if(si->sip != NULL && si->sip->frame_req>0){
5295                 fid=(int)si->sip->extra_info;
5296                 add_fid(tvb, pinfo, tree, 0, 0, fid);
5297         }
5298
5299         /* remaining */
5300         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5301         offset += 2;
5302
5303         /* data compaction mode */
5304         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
5305         offset += 2;
5306
5307         /* 2 reserved bytes */
5308         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5309         offset += 2;
5310
5311         /* data len */
5312         datalen = tvb_get_letohs(tvb, offset);
5313         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5314         offset += 2;
5315
5316         if (check_col(pinfo->cinfo, COL_INFO))
5317                 col_append_fstr(pinfo->cinfo, COL_INFO,
5318                                 ", %u byte%s", datalen,
5319                                 (datalen == 1) ? "" : "s");
5320
5321         /* data offset */
5322         dataoffset=tvb_get_letohs(tvb, offset);
5323         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5324         offset += 2;
5325
5326         /* 10 reserved bytes */
5327         /* XXX - first 2 bytes are data length high, not reserved */
5328         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
5329         offset += 10;
5330
5331         BYTE_COUNT;
5332
5333         /* file data, might be DCERPC on a pipe */
5334         if(bc){
5335                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5336                     top_tree, offset, bc, datalen, 0, fid);
5337                 bc = 0;
5338         }
5339
5340         END_OF_SMB
5341
5342         /* call AndXCommand (if there are any) */
5343         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5344
5345         return offset;
5346 }
5347
5348 static int
5349 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5350 {
5351         guint32 ofs=0;
5352         guint8  wc, cmd=0xff;
5353         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
5354         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5355         unsigned int fid=0;
5356         guint16 mode = 0;
5357
5358
5359         WORD_COUNT;
5360
5361         /* next smb command */
5362         cmd = tvb_get_guint8(tvb, offset);
5363         if(cmd!=0xff){
5364                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5365         } else {
5366                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5367         }
5368         offset += 1;
5369
5370         /* reserved byte */
5371         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5372         offset += 1;
5373
5374         /* andxoffset */
5375         andxoffset = tvb_get_letohs(tvb, offset);
5376         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5377         offset += 2;
5378
5379         /* fid */
5380         fid = tvb_get_letohs(tvb, offset);
5381         add_fid(tvb, pinfo, tree, offset, 2, fid);
5382         offset += 2;
5383         if (!pinfo->fd->flags.visited) {
5384                 /* remember the FID for the processing of the response */
5385                 si->sip->extra_info=(void *)fid;
5386         }
5387
5388         /* offset */
5389         ofs = tvb_get_letohl(tvb, offset);
5390         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5391         offset += 4;
5392
5393         /* reserved */
5394         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5395         offset += 4;
5396
5397         /* mode */
5398         mode = tvb_get_letohs(tvb, offset);
5399         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
5400
5401         /* remaining */
5402         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5403         offset += 2;
5404
5405         /* XXX - data length high */
5406         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5407         offset += 2;
5408
5409         /* data len */
5410         datalen = tvb_get_letohs(tvb, offset);
5411         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5412         offset += 2;
5413
5414         /* data offset */
5415         dataoffset=tvb_get_letohs(tvb, offset);
5416         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5417         offset += 2;
5418
5419         /* FIXME: handle Large (48-bit) byte/offset to COL_INFO */
5420         if (check_col(pinfo->cinfo, COL_INFO))
5421                 col_append_fstr(pinfo->cinfo, COL_INFO,
5422                                 ", %u byte%s at offset %u", datalen,
5423                                 (datalen == 1) ? "" : "s", ofs);
5424
5425         if(wc==14){
5426                 /* high offset */
5427                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5428                 offset += 4;
5429         }
5430
5431         BYTE_COUNT;
5432
5433         /* if both the MessageStart and the  WriteRawNamedPipe flags are set
5434            the first two bytes of the payload is the length of the data
5435            also this tells us that this is indeed the IPC$ share
5436            (if we didnt already know that 
5437         */
5438         if((mode&(WRITE_MODE_MESSAGE_START|WRITE_MODE_RAW))==(WRITE_MODE_MESSAGE_START|WRITE_MODE_RAW)){
5439                 proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, TRUE);
5440                 offset += 2;
5441                 dataoffset += 2;
5442                 bc -= 2;
5443                 datalen -= 2;
5444                 if(si->sip){
5445                         si->sip->flags|=SMB_SIF_TID_IS_IPC;
5446                 }
5447         }
5448
5449         /* file data, might be DCERPC on a pipe */
5450         if (bc != 0) {
5451                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5452                     top_tree, offset, bc, datalen, 0, fid);
5453                 bc = 0;
5454         }
5455
5456         END_OF_SMB
5457
5458         /* call AndXCommand (if there are any) */
5459         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5460
5461         return offset;
5462 }
5463
5464 static int
5465 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5466 {
5467         guint8  wc, cmd=0xff;
5468         guint16 andxoffset=0, bc, datalen=0;
5469         smb_info_t *si;
5470
5471         WORD_COUNT;
5472
5473         /* next smb command */
5474         cmd = tvb_get_guint8(tvb, offset);
5475         if(cmd!=0xff){
5476                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5477         } else {
5478                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5479         }
5480         offset += 1;
5481
5482         /* reserved byte */
5483         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5484         offset += 1;
5485
5486         /* andxoffset */
5487         andxoffset = tvb_get_letohs(tvb, offset);
5488         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5489         offset += 2;
5490
5491         /* If we have seen the request, then print which FID this refers to */
5492         si = (smb_info_t *)pinfo->private_data;
5493         /* first check if we have seen the request */
5494         if(si->sip != NULL && si->sip->frame_req>0){
5495                 add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
5496         }
5497
5498         /* write count */
5499         datalen = tvb_get_letohs(tvb, offset);
5500         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
5501         offset += 2;
5502
5503         if (check_col(pinfo->cinfo, COL_INFO))
5504                 col_append_fstr(pinfo->cinfo, COL_INFO,
5505                                 ", %u byte%s", datalen,
5506                                 (datalen == 1) ? "" : "s");
5507
5508         /* remaining */
5509         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5510         offset += 2;
5511
5512         /* 4 reserved bytes */
5513         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5514         offset += 4;
5515
5516         BYTE_COUNT;
5517
5518         END_OF_SMB
5519
5520         /* call AndXCommand (if there are any) */
5521         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5522
5523         return offset;
5524 }
5525
5526
5527 static const true_false_string tfs_setup_action_guest = {
5528         "Logged in as GUEST",
5529         "Not logged in as GUEST"
5530 };
5531 static int
5532 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5533 {
5534         guint16 mask;
5535         proto_item *item = NULL;
5536         proto_tree *tree = NULL;
5537
5538         mask = tvb_get_letohs(tvb, offset);
5539
5540         if(parent_tree){
5541                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5542                         "Action: 0x%04x", mask);
5543                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
5544         }
5545
5546         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
5547                 tvb, offset, 2, mask);
5548
5549         offset += 2;
5550
5551         return offset;
5552 }
5553
5554
5555 static int
5556 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5557 {
5558         guint8  wc, cmd=0xff;
5559         guint16 bc;
5560         guint16 andxoffset=0;
5561         smb_info_t *si = pinfo->private_data;
5562         int an_len;
5563         const char *an;
5564         int dn_len;
5565         const char *dn;
5566         guint16 pwlen=0;
5567         guint16 sbloblen=0;
5568         guint16 apwlen=0, upwlen=0;
5569
5570         WORD_COUNT;
5571
5572         /* next smb command */
5573         cmd = tvb_get_guint8(tvb, offset);
5574         if(cmd!=0xff){
5575                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5576         } else {
5577                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5578         }
5579         offset += 1;
5580
5581         /* reserved byte */
5582         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5583         offset += 1;
5584
5585         /* andxoffset */
5586         andxoffset = tvb_get_letohs(tvb, offset);
5587         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5588         offset += 2;
5589
5590         /* Maximum Buffer Size */
5591         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
5592         offset += 2;
5593
5594         /* Maximum Multiplex Count */
5595         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
5596         offset += 2;
5597
5598         /* VC Number */
5599         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
5600         offset += 2;
5601
5602         /* session key */
5603         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
5604         offset += 4;
5605
5606         switch (wc) {
5607         case 10:
5608                 /* password length, ASCII*/
5609                 pwlen = tvb_get_letohs(tvb, offset);
5610                 proto_tree_add_uint(tree, hf_smb_password_len,
5611                         tvb, offset, 2, pwlen);
5612                 offset += 2;
5613
5614                 /* 4 reserved bytes */
5615                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5616                 offset += 4;
5617
5618                 break;
5619
5620         case 12:
5621                 /* security blob length */
5622                 sbloblen = tvb_get_letohs(tvb, offset);
5623                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5624                 offset += 2;
5625
5626                 /* 4 reserved bytes */
5627                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5628                 offset += 4;
5629
5630                 /* capabilities */
5631                 dissect_negprot_capabilities(tvb, tree, offset);
5632                 offset += 4;
5633
5634                 break;
5635
5636         case 13:
5637                 /* password length, ANSI*/
5638                 apwlen = tvb_get_letohs(tvb, offset);
5639                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
5640                         tvb, offset, 2, apwlen);
5641                 offset += 2;
5642
5643                 /* password length, Unicode*/
5644                 upwlen = tvb_get_letohs(tvb, offset);
5645                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
5646                         tvb, offset, 2, upwlen);
5647                 offset += 2;
5648
5649                 /* 4 reserved bytes */
5650                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5651                 offset += 4;
5652
5653                 /* capabilities */
5654                 dissect_negprot_capabilities(tvb, tree, offset);
5655                 offset += 4;
5656
5657                 break;
5658         }
5659
5660         BYTE_COUNT;
5661
5662         if (wc==12) {
5663                 proto_item *blob_item;
5664
5665                 /* security blob */
5666
5667                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
5668                                                 tvb, offset, sbloblen, TRUE);
5669
5670                 /* As an optimization, because Windows is perverse,
5671                    we check to see if NTLMSSP is the first part of the 
5672                    blob, and if so, call the NTLMSSP dissector,
5673                    otherwise we call the GSS-API dissector. This is because
5674                    Windows can request RAW NTLMSSP, but will happily handle
5675                    a client that wraps NTLMSSP in SPNEGO
5676                 */
5677
5678                 if(sbloblen){
5679                         tvbuff_t *blob_tvb;
5680                         proto_tree *blob_tree;
5681
5682                         blob_tree = proto_item_add_subtree(blob_item, 
5683                                                            ett_smb_secblob);
5684                         CHECK_BYTE_COUNT(sbloblen);
5685
5686                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
5687                                                   sbloblen);
5688
5689                         if (si && si->ct && si->ct->raw_ntlmssp && 
5690                             !strncmp("NTLMSSP", 
5691                                      tvb_get_ptr(tvb, offset, 7), 7)) {
5692                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
5693                                          blob_tree);
5694
5695                         }
5696                         else {
5697                           call_dissector(gssapi_handle, blob_tvb, 
5698                                          pinfo, blob_tree);
5699                         }
5700
5701                         COUNT_BYTES(sbloblen);
5702                 }
5703
5704                 /* OS */
5705                 an = get_unicode_or_ascii_string(tvb, &offset,
5706                         si->unicode, &an_len, FALSE, FALSE, &bc);
5707                 if (an == NULL)
5708                         goto endofcommand;
5709                 proto_tree_add_string(tree, hf_smb_os, tvb,
5710                         offset, an_len, an);
5711                 COUNT_BYTES(an_len);
5712
5713                 /* LANMAN */
5714                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5715                  * padding/null string/whatever in front of this. W2K doesn't
5716                  * appear to. I suspect that's a bug that got fixed; I also
5717                  * suspect that, in practice, nobody ever looks at that field
5718                  * because the bug didn't appear to get fixed until NT 5.0....
5719                  */
5720                 an = get_unicode_or_ascii_string(tvb, &offset,
5721                         si->unicode, &an_len, FALSE, FALSE, &bc);
5722                 if (an == NULL)
5723                         goto endofcommand;
5724                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5725                         offset, an_len, an);
5726                 COUNT_BYTES(an_len);
5727
5728                 /* Primary domain */
5729                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5730                  * byte in front of this, at least if all the strings are
5731                  * ASCII and the account name is empty. Another bug?
5732                  */
5733                 dn = get_unicode_or_ascii_string(tvb, &offset,
5734                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5735                 if (dn == NULL)
5736                         goto endofcommand;
5737                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5738                         offset, dn_len, dn);
5739                 COUNT_BYTES(dn_len);
5740         } else {
5741                 switch (wc) {
5742
5743                 case 10:
5744                         if(pwlen){
5745                                 /* password, ASCII */
5746                                 CHECK_BYTE_COUNT(pwlen);
5747                                 proto_tree_add_item(tree, hf_smb_password,
5748                                         tvb, offset, pwlen, TRUE);
5749                                 COUNT_BYTES(pwlen);
5750                         }
5751
5752                         break;
5753
5754                 case 13:
5755                         if(apwlen){
5756                                 /* password, ANSI */
5757                                 CHECK_BYTE_COUNT(apwlen);
5758                                 proto_tree_add_item(tree, hf_smb_ansi_password,
5759                                         tvb, offset, apwlen, TRUE);
5760                                 COUNT_BYTES(apwlen);
5761                         }
5762
5763                         if(upwlen){
5764                                 proto_item *item;
5765
5766                                 /* password, Unicode */
5767                                 CHECK_BYTE_COUNT(upwlen);
5768                                 item = proto_tree_add_item(tree, hf_smb_unicode_password,
5769                                         tvb, offset, upwlen, TRUE);
5770
5771                                 if (upwlen > 24) {
5772                                         proto_tree *subtree;
5773
5774                                         subtree = proto_item_add_subtree(item, ett_smb_unicode_password);
5775
5776                                         dissect_ntlmv2_response(
5777                                                 tvb, subtree, offset, upwlen);
5778                                 }
5779
5780                                 COUNT_BYTES(upwlen);
5781                         }
5782
5783                         break;
5784                 }
5785
5786                 /* Account Name */
5787                 an = get_unicode_or_ascii_string(tvb, &offset,
5788                         si->unicode, &an_len, FALSE, FALSE, &bc);
5789                 if (an == NULL)
5790                         goto endofcommand;
5791                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
5792                         an);
5793                 COUNT_BYTES(an_len);
5794
5795                 /* Primary domain */
5796                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5797                  * byte in front of this, at least if all the strings are
5798                  * ASCII and the account name is empty. Another bug?
5799                  */
5800                 dn = get_unicode_or_ascii_string(tvb, &offset,
5801                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5802                 if (dn == NULL)
5803                         goto endofcommand;
5804                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5805                         offset, dn_len, dn);
5806                 COUNT_BYTES(dn_len);
5807
5808                 if (check_col(pinfo->cinfo, COL_INFO)) {
5809                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
5810
5811                         if (!dn[0] && !an[0])
5812                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5813                                                 "anonymous");
5814                         else
5815                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5816                                                 "%s\\%s", dn,an);
5817                 }
5818
5819                 /* OS */
5820                 an = get_unicode_or_ascii_string(tvb, &offset,
5821                         si->unicode, &an_len, FALSE, FALSE, &bc);
5822                 if (an == NULL)
5823                         goto endofcommand;
5824                 proto_tree_add_string(tree, hf_smb_os, tvb,
5825                         offset, an_len, an);
5826                 COUNT_BYTES(an_len);
5827
5828                 /* LANMAN */
5829                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5830                  * padding/null string/whatever in front of this. W2K doesn't
5831                  * appear to. I suspect that's a bug that got fixed; I also
5832                  * suspect that, in practice, nobody ever looks at that field
5833                  * because the bug didn't appear to get fixed until NT 5.0....
5834                  */
5835                 an = get_unicode_or_ascii_string(tvb, &offset,
5836                         si->unicode, &an_len, FALSE, FALSE, &bc);
5837                 if (an == NULL)
5838                         goto endofcommand;
5839                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5840                         offset, an_len, an);
5841                 COUNT_BYTES(an_len);
5842         }
5843
5844         END_OF_SMB
5845
5846         /* call AndXCommand (if there are any) */
5847         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5848
5849         return offset;
5850 }
5851
5852 static int
5853 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5854 {
5855         guint8  wc, cmd=0xff;
5856         guint16 andxoffset=0, bc;
5857         guint16 sbloblen=0;
5858         smb_info_t *si = pinfo->private_data;
5859         int an_len;
5860         const char *an;
5861
5862         WORD_COUNT;
5863
5864         /* next smb command */
5865         cmd = tvb_get_guint8(tvb, offset);
5866         if(cmd!=0xff){
5867                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5868         } else {
5869                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5870         }
5871         offset += 1;
5872
5873         /* reserved byte */
5874         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5875         offset += 1;
5876
5877         /* andxoffset */
5878         andxoffset = tvb_get_letohs(tvb, offset);
5879         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5880         offset += 2;
5881
5882         /* flags */
5883         offset = dissect_setup_action(tvb, tree, offset);
5884
5885         if(wc==4){
5886                 /* security blob length */
5887                 sbloblen = tvb_get_letohs(tvb, offset);
5888                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5889                 offset += 2;
5890         }
5891
5892         BYTE_COUNT;
5893
5894         if(wc==4) {
5895                 proto_item *blob_item;
5896
5897                 /* security blob */
5898
5899                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
5900                                                 tvb, offset, sbloblen, TRUE);
5901
5902                 if(sbloblen){
5903                         tvbuff_t *blob_tvb;
5904                         proto_tree *blob_tree;
5905
5906                         blob_tree = proto_item_add_subtree(blob_item, 
5907                                                            ett_smb_secblob);
5908                         CHECK_BYTE_COUNT(sbloblen);
5909
5910                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
5911                                                     sbloblen);
5912
5913                         if (si && si->ct && si->ct->raw_ntlmssp && 
5914                             !strncmp("NTLMSSP", 
5915                                      tvb_get_ptr(tvb, offset, 7), 7)) {
5916                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
5917                                          blob_tree);
5918
5919                         }
5920                         else {
5921                           call_dissector(gssapi_handle, blob_tvb, pinfo, 
5922                                          blob_tree);
5923
5924                         }
5925
5926                         COUNT_BYTES(sbloblen);
5927                 }
5928         }
5929
5930         /* OS */
5931         an = get_unicode_or_ascii_string(tvb, &offset,
5932                 si->unicode, &an_len, FALSE, FALSE, &bc);
5933         if (an == NULL)
5934                 goto endofcommand;
5935         proto_tree_add_string(tree, hf_smb_os, tvb,
5936                 offset, an_len, an);
5937         COUNT_BYTES(an_len);
5938
5939         /* LANMAN */
5940         an = get_unicode_or_ascii_string(tvb, &offset,
5941                 si->unicode, &an_len, FALSE, FALSE, &bc);
5942         if (an == NULL)
5943                 goto endofcommand;
5944         proto_tree_add_string(tree, hf_smb_lanman, tvb,
5945                 offset, an_len, an);
5946         COUNT_BYTES(an_len);
5947
5948         if(wc==3) {
5949                 /* Primary domain */
5950                 an = get_unicode_or_ascii_string(tvb, &offset,
5951                         si->unicode, &an_len, FALSE, FALSE, &bc);
5952                 if (an == NULL)
5953                         goto endofcommand;
5954                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5955                         offset, an_len, an);
5956                 COUNT_BYTES(an_len);
5957         }
5958
5959         END_OF_SMB
5960
5961         /* call AndXCommand (if there are any) */
5962         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5963
5964         return offset;
5965 }
5966
5967
5968 static int
5969 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5970 {
5971         guint8  wc, cmd=0xff;
5972         guint16 andxoffset=0;
5973         guint16 bc;
5974
5975         WORD_COUNT;
5976
5977         /* next smb command */
5978         cmd = tvb_get_guint8(tvb, offset);
5979         if(cmd!=0xff){
5980                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5981         } else {
5982                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5983         }
5984         offset += 1;
5985
5986         /* reserved byte */
5987         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5988         offset += 1;
5989
5990         /* andxoffset */
5991         andxoffset = tvb_get_letohs(tvb, offset);
5992         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5993         offset += 2;
5994
5995         BYTE_COUNT;
5996
5997         END_OF_SMB
5998
5999         /* call AndXCommand (if there are any) */
6000         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6001
6002         return offset;
6003 }
6004
6005
6006 static const true_false_string tfs_connect_support_search = {
6007         "Exclusive search bits supported",
6008         "Exclusive search bits not supported"
6009 };
6010 static const true_false_string tfs_connect_support_in_dfs = {
6011         "Share is in Dfs",
6012         "Share isn't in Dfs"
6013 };
6014
6015 static int
6016 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6017 {
6018         guint16 mask;
6019         proto_item *item = NULL;
6020         proto_tree *tree = NULL;
6021
6022         mask = tvb_get_letohs(tvb, offset);
6023
6024         if(parent_tree){
6025                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6026                         "Optional Support: 0x%04x", mask);
6027                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
6028         }
6029
6030         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
6031                 tvb, offset, 2, mask);
6032         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
6033                 tvb, offset, 2, mask);
6034
6035         offset += 2;
6036
6037         return offset;
6038 }
6039
6040 static const true_false_string tfs_disconnect_tid = {
6041         "DISCONNECT TID",
6042         "Do NOT disconnect TID"
6043 };
6044
6045 static int
6046 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6047 {
6048         guint16 mask;
6049         proto_item *item = NULL;
6050         proto_tree *tree = NULL;
6051
6052         mask = tvb_get_letohs(tvb, offset);
6053
6054         if(parent_tree){
6055                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6056                         "Flags: 0x%04x", mask);
6057                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
6058         }
6059
6060         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
6061                 tvb, offset, 2, mask);
6062
6063         offset += 2;
6064
6065         return offset;
6066 }
6067
6068 static int
6069 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6070 {
6071         guint8  wc, cmd=0xff;
6072         guint16 bc;
6073         guint16 andxoffset=0, pwlen=0;
6074         smb_info_t *si = pinfo->private_data;
6075         int an_len;
6076         const char *an;
6077
6078         WORD_COUNT;
6079
6080         /* next smb command */
6081         cmd = tvb_get_guint8(tvb, offset);
6082         if(cmd!=0xff){
6083                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6084         } else {
6085                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
6086         }
6087         offset += 1;
6088
6089         /* reserved byte */
6090         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6091         offset += 1;
6092
6093         /* andxoffset */
6094         andxoffset = tvb_get_letohs(tvb, offset);
6095         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6096         offset += 2;
6097
6098         /* flags */
6099         offset = dissect_connect_flags(tvb, tree, offset);
6100
6101         /* password length*/
6102         pwlen = tvb_get_letohs(tvb, offset);
6103         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
6104         offset += 2;
6105
6106         BYTE_COUNT;
6107
6108         /* password */
6109         CHECK_BYTE_COUNT(pwlen);
6110         proto_tree_add_item(tree, hf_smb_password,
6111                 tvb, offset, pwlen, TRUE);
6112         COUNT_BYTES(pwlen);
6113
6114         /* Path */
6115         an = get_unicode_or_ascii_string(tvb, &offset,
6116                 si->unicode, &an_len, FALSE, FALSE, &bc);
6117         if (an == NULL)
6118                 goto endofcommand;
6119         proto_tree_add_string(tree, hf_smb_path, tvb,
6120                 offset, an_len, an);
6121         COUNT_BYTES(an_len);
6122
6123         if (check_col(pinfo->cinfo, COL_INFO)) {
6124                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
6125         }
6126
6127         /*
6128          * NOTE: the Service string is always ASCII, even if the
6129          * "strings are Unicode" bit is set in the flags2 field
6130          * of the SMB.
6131          */
6132
6133         /* Service */
6134         /* XXX - what if this runs past bc? */
6135         an_len = tvb_strsize(tvb, offset);
6136         CHECK_BYTE_COUNT(an_len);
6137         an = tvb_get_ptr(tvb, offset, an_len);
6138         proto_tree_add_string(tree, hf_smb_service, tvb,
6139                 offset, an_len, an);
6140         COUNT_BYTES(an_len);
6141
6142         END_OF_SMB
6143
6144         /* call AndXCommand (if there are any) */
6145         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6146
6147         return offset;
6148 }
6149
6150
6151 static int
6152 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6153 {
6154         guint8  wc, wleft, cmd=0xff;
6155         guint16 andxoffset=0;
6156         guint16 bc;
6157         int an_len;
6158         const char *an;
6159         smb_info_t *si = pinfo->private_data;
6160
6161         WORD_COUNT;
6162
6163         wleft = wc;     /* this is at least 1 */
6164
6165         /* next smb command */
6166         cmd = tvb_get_guint8(tvb, offset);
6167         if(cmd!=0xff){
6168                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6169         } else {
6170                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
6171         }
6172         offset += 1;
6173
6174         /* reserved byte */
6175         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6176         offset += 1;
6177
6178         wleft--;
6179         if (wleft == 0)
6180                 goto bytecount;
6181
6182         /* andxoffset */
6183         andxoffset = tvb_get_letohs(tvb, offset);
6184         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6185         offset += 2;
6186         wleft--;
6187         if (wleft == 0)
6188                 goto bytecount;
6189
6190         /* flags */
6191         offset = dissect_connect_support_bits(tvb, tree, offset);
6192         wleft--;
6193
6194         /* XXX - I've seen captures where this is 7, but I have no
6195            idea how to dissect it.  I'm guessing the third word
6196            contains connect support bits, which looks plausible
6197            from the values I've seen. */
6198
6199         while (wleft != 0) {
6200                 proto_tree_add_text(tree, tvb, offset, 2,
6201                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
6202                 offset += 2;
6203                 wleft--;
6204         }
6205
6206         BYTE_COUNT;
6207
6208         /*
6209          * NOTE: even though the SNIA CIFS spec doesn't say there's
6210          * a "Service" string if there's a word count of 2, the
6211          * document at
6212          *
6213          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
6214          *
6215          * (it's in an ugly format - text intended to be sent to a
6216          * printer, with backspaces and overstrikes used for boldfacing
6217          * and underlining; UNIX "col -b" can be used to strip the
6218          * overstrikes out) says there's a "Service" string there, and
6219          * some network traffic has it.
6220          */
6221
6222         /*
6223          * NOTE: the Service string is always ASCII, even if the
6224          * "strings are Unicode" bit is set in the flags2 field
6225          * of the SMB.
6226          */
6227
6228         /* Service */
6229         /* XXX - what if this runs past bc? */
6230         an_len = tvb_strsize(tvb, offset);
6231         CHECK_BYTE_COUNT(an_len);
6232         an = tvb_get_ptr(tvb, offset, an_len);
6233         proto_tree_add_string(tree, hf_smb_service, tvb,
6234                 offset, an_len, an);
6235         COUNT_BYTES(an_len);
6236
6237         /* Now when we know the service type, store it so that we know it for later commands down
6238            this tree */
6239         if(!pinfo->fd->flags.visited){
6240                 /* Remove any previous entry for this TID */
6241                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
6242                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
6243                 }
6244                 if(strcmp(an,"IPC") == 0){
6245                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
6246                 } else {
6247                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
6248                 }
6249         }
6250
6251
6252         if(wc==3){
6253                 if (bc != 0) {
6254                         /*
6255                          * Sometimes this isn't present.
6256                          */
6257
6258                         /* Native FS */
6259                         an = get_unicode_or_ascii_string(tvb, &offset,
6260                                 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
6261                                 &bc);
6262                         if (an == NULL)
6263                                 goto endofcommand;
6264                         proto_tree_add_string(tree, hf_smb_fs, tvb,
6265                                 offset, an_len, an);
6266                         COUNT_BYTES(an_len);
6267                 }
6268         }
6269
6270         END_OF_SMB
6271
6272         /* call AndXCommand (if there are any) */
6273         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6274
6275         return offset;
6276 }
6277
6278
6279
6280 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6281    NT Transaction command  begins here
6282    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
6283 #define NT_TRANS_CREATE         1
6284 #define NT_TRANS_IOCTL          2
6285 #define NT_TRANS_SSD            3
6286 #define NT_TRANS_NOTIFY         4
6287 #define NT_TRANS_RENAME         5
6288 #define NT_TRANS_QSD            6
6289 #define NT_TRANS_GET_USER_QUOTA 7
6290 #define NT_TRANS_SET_USER_QUOTA 8
6291 const value_string nt_cmd_vals[] = {
6292         {NT_TRANS_CREATE,               "NT CREATE"},
6293         {NT_TRANS_IOCTL,                "NT IOCTL"},
6294         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
6295         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
6296         {NT_TRANS_RENAME,               "NT RENAME"},
6297         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
6298         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
6299         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
6300         {0, NULL}
6301 };
6302
6303 static const value_string nt_ioctl_isfsctl_vals[] = {
6304         {0,     "Device IOCTL"},
6305         {1,     "FS control : FSCTL"},
6306         {0, NULL}
6307 };
6308
6309 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
6310 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
6311         "Apply the command to share root handle (MUST BE Dfs)",
6312         "Apply to this share",
6313 };
6314
6315 static const value_string nt_notify_action_vals[] = {
6316         {1,     "ADDED (object was added"},
6317         {2,     "REMOVED (object was removed)"},
6318         {3,     "MODIFIED (object was modified)"},
6319         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
6320         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
6321         {6,     "ADDED_STREAM (a stream was added)"},
6322         {7,     "REMOVED_STREAM (a stream was removed)"},
6323         {8,     "MODIFIED_STREAM (a stream was modified)"},
6324         {0, NULL}
6325 };
6326
6327 static const value_string watch_tree_vals[] = {
6328         {0,     "Current directory only"},
6329         {1,     "Subdirectories also"},
6330         {0, NULL}
6331 };
6332
6333 #define NT_NOTIFY_STREAM_WRITE  0x00000800
6334 #define NT_NOTIFY_STREAM_SIZE   0x00000400
6335 #define NT_NOTIFY_STREAM_NAME   0x00000200
6336 #define NT_NOTIFY_SECURITY      0x00000100
6337 #define NT_NOTIFY_EA            0x00000080
6338 #define NT_NOTIFY_CREATION      0x00000040
6339 #define NT_NOTIFY_LAST_ACCESS   0x00000020
6340 #define NT_NOTIFY_LAST_WRITE    0x00000010
6341 #define NT_NOTIFY_SIZE          0x00000008
6342 #define NT_NOTIFY_ATTRIBUTES    0x00000004
6343 #define NT_NOTIFY_DIR_NAME      0x00000002
6344 #define NT_NOTIFY_FILE_NAME     0x00000001
6345 static const true_false_string tfs_nt_notify_stream_write = {
6346         "Notify on changes to STREAM WRITE",
6347         "Do NOT notify on changes to stream write",
6348 };
6349 static const true_false_string tfs_nt_notify_stream_size = {
6350         "Notify on changes to STREAM SIZE",
6351         "Do NOT notify on changes to stream size",
6352 };
6353 static const true_false_string tfs_nt_notify_stream_name = {
6354         "Notify on changes to STREAM NAME",
6355         "Do NOT notify on changes to stream name",
6356 };
6357 static const true_false_string tfs_nt_notify_security = {
6358         "Notify on changes to SECURITY",
6359         "Do NOT notify on changes to security",
6360 };
6361 static const true_false_string tfs_nt_notify_ea = {
6362         "Notify on changes to EA",
6363         "Do NOT notify on changes to EA",
6364 };
6365 static const true_false_string tfs_nt_notify_creation = {
6366         "Notify on changes to CREATION TIME",
6367         "Do NOT notify on changes to creation time",
6368 };
6369 static const true_false_string tfs_nt_notify_last_access = {
6370         "Notify on changes to LAST ACCESS TIME",
6371         "Do NOT notify on changes to last access time",
6372 };
6373 static const true_false_string tfs_nt_notify_last_write = {
6374         "Notify on changes to LAST WRITE TIME",
6375         "Do NOT notify on changes to last write time",
6376 };
6377 static const true_false_string tfs_nt_notify_size = {
6378         "Notify on changes to SIZE",
6379         "Do NOT notify on changes to size",
6380 };
6381 static const true_false_string tfs_nt_notify_attributes = {
6382         "Notify on changes to ATTRIBUTES",
6383         "Do NOT notify on changes to attributes",
6384 };
6385 static const true_false_string tfs_nt_notify_dir_name = {
6386         "Notify on changes to DIR NAME",
6387         "Do NOT notify on changes to dir name",
6388 };
6389 static const true_false_string tfs_nt_notify_file_name = {
6390         "Notify on changes to FILE NAME",
6391         "Do NOT notify on changes to file name",
6392 };
6393
6394 static const value_string create_disposition_vals[] = {
6395         {0,     "Supersede (supersede existing file (if it exists))"},
6396         {1,     "Open (if file exists open it, else fail)"},
6397         {2,     "Create (if file exists fail, else create it)"},
6398         {3,     "Open If (if file exists open it, else create it)"},
6399         {4,     "Overwrite (if file exists overwrite, else fail)"},
6400         {5,     "Overwrite If (if file exists overwrite, else create it)"},
6401         {0, NULL}
6402 };
6403
6404 static const value_string impersonation_level_vals[] = {
6405         {0,     "Anonymous"},
6406         {1,     "Identification"},
6407         {2,     "Impersonation"},
6408         {3,     "Delegation"},
6409         {0, NULL}
6410 };
6411
6412 static const true_false_string tfs_nt_security_flags_context_tracking = {
6413         "Security tracking mode is DYNAMIC",
6414         "Security tracking mode is STATIC",
6415 };
6416
6417 static const true_false_string tfs_nt_security_flags_effective_only = {
6418         "ONLY ENABLED aspects of the client's security context are available",
6419         "ALL aspects of the client's security context are available",
6420 };
6421
6422 static const true_false_string tfs_nt_create_bits_oplock = {
6423         "Requesting OPLOCK",
6424         "Does NOT request oplock"
6425 };
6426
6427 static const true_false_string tfs_nt_create_bits_boplock = {
6428         "Requesting BATCH OPLOCK",
6429         "Does NOT request batch oplock"
6430 };
6431
6432 /*
6433  * XXX - must be a directory, and can be a file, or can be a directory,
6434  * and must be a file?
6435  */
6436 static const true_false_string tfs_nt_create_bits_dir = {
6437         "Target of open MUST be a DIRECTORY",
6438         "Target of open can be a file"
6439 };
6440
6441 static const true_false_string tfs_nt_create_bits_ext_resp = {
6442   "Extended responses required",
6443   "Extended responses NOT required"
6444 };
6445
6446 static const true_false_string tfs_nt_access_mask_generic_read = {
6447         "GENERIC READ is set",
6448         "Generic read is NOT set"
6449 };
6450 static const true_false_string tfs_nt_access_mask_generic_write = {
6451         "GENERIC WRITE is set",
6452         "Generic write is NOT set"
6453 };
6454 static const true_false_string tfs_nt_access_mask_generic_execute = {
6455         "GENERIC EXECUTE is set",
6456         "Generic execute is NOT set"
6457 };
6458 static const true_false_string tfs_nt_access_mask_generic_all = {
6459         "GENERIC ALL is set",
6460         "Generic all is NOT set"
6461 };
6462 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
6463         "MAXIMUM ALLOWED is set",
6464         "Maximum allowed is NOT set"
6465 };
6466 static const true_false_string tfs_nt_access_mask_system_security = {
6467         "SYSTEM SECURITY is set",
6468         "System security is NOT set"
6469 };
6470 static const true_false_string tfs_nt_access_mask_synchronize = {
6471         "Can wait on handle to SYNCHRONIZE on completion of I/O",
6472         "Can NOT wait on handle to synchronize on completion of I/O"
6473 };
6474 static const true_false_string tfs_nt_access_mask_write_owner = {
6475         "Can WRITE OWNER (take ownership)",
6476         "Can NOT write owner (take ownership)"
6477 };
6478 static const true_false_string tfs_nt_access_mask_write_dac = {
6479         "OWNER may WRITE the DAC",
6480         "Owner may NOT write to the DAC"
6481 };
6482 static const true_false_string tfs_nt_access_mask_read_control = {
6483         "READ ACCESS to owner, group and ACL of the SID",
6484         "Read access is NOT granted to owner, group and ACL of the SID"
6485 };
6486 static const true_false_string tfs_nt_access_mask_delete = {
6487         "DELETE access",
6488         "NO delete access"
6489 };
6490 static const true_false_string tfs_nt_access_mask_write_attributes = {
6491         "WRITE ATTRIBUTES access",
6492         "NO write attributes access"
6493 };
6494 static const true_false_string tfs_nt_access_mask_read_attributes = {
6495         "READ ATTRIBUTES access",
6496         "NO read attributes access"
6497 };
6498 static const true_false_string tfs_nt_access_mask_delete_child = {
6499         "DELETE CHILD access",
6500         "NO delete child access"
6501 };
6502 static const true_false_string tfs_nt_access_mask_execute = {
6503         "EXECUTE access",
6504         "NO execute access"
6505 };
6506 static const true_false_string tfs_nt_access_mask_write_ea = {
6507         "WRITE EXTENDED ATTRIBUTES access",
6508         "NO write extended attributes access"
6509 };
6510 static const true_false_string tfs_nt_access_mask_read_ea = {
6511         "READ EXTENDED ATTRIBUTES access",
6512         "NO read extended attributes access"
6513 };
6514 static const true_false_string tfs_nt_access_mask_append = {
6515         "APPEND access",
6516         "NO append access"
6517 };
6518 static const true_false_string tfs_nt_access_mask_write = {
6519         "WRITE access",
6520         "NO write access"
6521 };
6522 static const true_false_string tfs_nt_access_mask_read = {
6523         "READ access",
6524         "NO read access"
6525 };
6526
6527 static const true_false_string tfs_nt_share_access_delete = {
6528         "Object can be shared for DELETE",
6529         "Object can NOT be shared for delete"
6530 };
6531 static const true_false_string tfs_nt_share_access_write = {
6532         "Object can be shared for WRITE",
6533         "Object can NOT be shared for write"
6534 };
6535 static const true_false_string tfs_nt_share_access_read = {
6536         "Object can be shared for READ",
6537         "Object can NOT be shared for read"
6538 };
6539
6540 static const value_string oplock_level_vals[] = {
6541         {0,     "No oplock granted"},
6542         {1,     "Exclusive oplock granted"},
6543         {2,     "Batch oplock granted"},
6544         {3,     "Level II oplock granted"},
6545         {0, NULL}
6546 };
6547
6548 static const value_string device_type_vals[] = {
6549         {0x00000001,    "Beep"},
6550         {0x00000002,    "CDROM"},
6551         {0x00000003,    "CDROM Filesystem"},
6552         {0x00000004,    "Controller"},
6553         {0x00000005,    "Datalink"},
6554         {0x00000006,    "Dfs"},
6555         {0x00000007,    "Disk"},
6556         {0x00000008,    "Disk Filesystem"},
6557         {0x00000009,    "Filesystem"},
6558         {0x0000000a,    "Inport Port"},
6559         {0x0000000b,    "Keyboard"},
6560         {0x0000000c,    "Mailslot"},
6561         {0x0000000d,    "MIDI-In"},
6562         {0x0000000e,    "MIDI-Out"},
6563         {0x0000000f,    "Mouse"},
6564         {0x00000010,    "Multi UNC Provider"},
6565         {0x00000011,    "Named Pipe"},
6566         {0x00000012,    "Network"},
6567         {0x00000013,    "Network Browser"},
6568         {0x00000014,    "Network Filesystem"},
6569         {0x00000015,    "NULL"},
6570         {0x00000016,    "Parallel Port"},
6571         {0x00000017,    "Physical card"},
6572         {0x00000018,    "Printer"},
6573         {0x00000019,    "Scanner"},
6574         {0x0000001a,    "Serial Mouse port"},
6575         {0x0000001b,    "Serial port"},
6576         {0x0000001c,    "Screen"},
6577         {0x0000001d,    "Sound"},
6578         {0x0000001e,    "Streams"},
6579         {0x0000001f,    "Tape"},
6580         {0x00000020,    "Tape Filesystem"},
6581         {0x00000021,    "Transport"},
6582         {0x00000022,    "Unknown"},
6583         {0x00000023,    "Video"},
6584         {0x00000024,    "Virtual Disk"},
6585         {0x00000025,    "WAVE-In"},
6586         {0x00000026,    "WAVE-Out"},
6587         {0x00000027,    "8042 Port"},
6588         {0x00000028,    "Network Redirector"},
6589         {0x00000029,    "Battery"},
6590         {0x0000002a,    "Bus Extender"},
6591         {0x0000002b,    "Modem"},
6592         {0x0000002c,    "VDM"},
6593         {0,     NULL}
6594 };
6595
6596 static const value_string is_directory_vals[] = {
6597         {0,     "This is NOT a directory"},
6598         {1,     "This is a DIRECTORY"},
6599         {0, NULL}
6600 };
6601
6602 typedef struct _nt_trans_data {
6603         int subcmd;
6604         guint32 sd_len;
6605         guint32 ea_len;
6606 } nt_trans_data;
6607
6608
6609
6610 static int
6611 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6612 {
6613         guint8 mask;
6614         proto_item *item = NULL;
6615         proto_tree *tree = NULL;
6616
6617         mask = tvb_get_guint8(tvb, offset);
6618
6619         if(parent_tree){
6620                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6621                         "Security Flags: 0x%02x", mask);
6622                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
6623         }
6624
6625         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
6626                 tvb, offset, 1, mask);
6627         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
6628                 tvb, offset, 1, mask);
6629
6630         offset += 1;
6631
6632         return offset;
6633 }
6634
6635 static int
6636 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6637 {
6638         guint32 mask;
6639         proto_item *item = NULL;
6640         proto_tree *tree = NULL;
6641
6642         mask = tvb_get_letohl(tvb, offset);
6643
6644         if(parent_tree){
6645                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6646                         "Share Access: 0x%08x", mask);
6647                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
6648         }
6649
6650         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
6651                 tvb, offset, 4, mask);
6652         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
6653                 tvb, offset, 4, mask);
6654         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
6655                 tvb, offset, 4, mask);
6656
6657         offset += 4;
6658
6659         return offset;
6660 }
6661
6662 /* FIXME: need to call dissect_nt_access_mask() instead */
6663
6664 static int
6665 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6666 {
6667         guint32 mask;
6668         proto_item *item = NULL;
6669         proto_tree *tree = NULL;
6670
6671         mask = tvb_get_letohl(tvb, offset);
6672
6673         if(parent_tree){
6674                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6675                         "Access Mask: 0x%08x", mask);
6676                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
6677         }
6678
6679         /*
6680          * Some of these bits come from
6681          *
6682          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6683          *
6684          * and others come from the section on ZwOpenFile in "Windows(R)
6685          * NT(R)/2000 Native API Reference".
6686          */
6687         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
6688                 tvb, offset, 4, mask);
6689         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
6690                 tvb, offset, 4, mask);
6691         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
6692                 tvb, offset, 4, mask);
6693         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
6694                 tvb, offset, 4, mask);
6695         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
6696                 tvb, offset, 4, mask);
6697         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
6698                 tvb, offset, 4, mask);
6699         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
6700                 tvb, offset, 4, mask);
6701         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
6702                 tvb, offset, 4, mask);
6703         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
6704                 tvb, offset, 4, mask);
6705         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
6706                 tvb, offset, 4, mask);
6707         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
6708                 tvb, offset, 4, mask);
6709         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
6710                 tvb, offset, 4, mask);
6711         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
6712                 tvb, offset, 4, mask);
6713         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
6714                 tvb, offset, 4, mask);
6715         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
6716                 tvb, offset, 4, mask);
6717         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
6718                 tvb, offset, 4, mask);
6719         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
6720                 tvb, offset, 4, mask);
6721         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
6722                 tvb, offset, 4, mask);
6723         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
6724                 tvb, offset, 4, mask);
6725         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
6726                 tvb, offset, 4, mask);
6727
6728         offset += 4;
6729
6730         return offset;
6731 }
6732
6733 static int
6734 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6735 {
6736         guint32 mask;
6737         proto_item *item = NULL;
6738         proto_tree *tree = NULL;
6739
6740         mask = tvb_get_letohl(tvb, offset);
6741
6742         if(parent_tree){
6743                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6744                         "Create Flags: 0x%08x", mask);
6745                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
6746         }
6747
6748         /*
6749          * XXX - it's 0x00000016 in at least one capture, but
6750          * Network Monitor doesn't say what the 0x00000010 bit is.
6751          * Does the Win32 API documentation, or NT Native API book,
6752          * suggest anything?
6753          *
6754          * That is the extended response desired bit ... RJS, from Samba
6755          * Well, maybe. Samba thinks it is, and uses it to encode
6756          * OpLock granted as the high order bit of the Action field
6757          * in the response. However, Windows does not do that. Or at least
6758          * Win2K doesn't.
6759          */
6760         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
6761                                tvb, offset, 4, mask);
6762         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
6763                 tvb, offset, 4, mask);
6764         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
6765                 tvb, offset, 4, mask);
6766         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
6767                 tvb, offset, 4, mask);
6768
6769         offset += 4;
6770
6771         return offset;
6772 }
6773
6774 /*
6775  * XXX - there are some more flags in the description of "ZwOpenFile()"
6776  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
6777  * the wire as well?  (The spec at
6778  *
6779  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6780  *
6781  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
6782  * via the SMB protocol.  The NT redirector should convert this option
6783  * to FILE_WRITE_THROUGH."
6784  *
6785  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
6786  * values one would infer from their position in the list of flags for
6787  * "ZwOpenFile()".  Most of the others probably have those values
6788  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
6789  * which might go over the wire (for the benefit of backup/restore software).
6790  */
6791 static const true_false_string tfs_nt_create_options_directory = {
6792         "File being created/opened must be a directory",
6793         "File being created/opened must not be a directory"
6794 };
6795 static const true_false_string tfs_nt_create_options_write_through = {
6796         "Writes should flush buffered data before completing",
6797         "Writes need not flush buffered data before completing"
6798 };
6799 static const true_false_string tfs_nt_create_options_sequential_only = {
6800         "The file will only be accessed sequentially",
6801         "The file might not only be accessed sequentially"
6802 };
6803 static const true_false_string tfs_nt_create_options_sync_io_alert = {
6804         "All operations SYNCHRONOUS, waits subject to termination from alert",
6805         "Operations NOT necessarily synchronous"
6806 };
6807 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
6808         "All operations SYNCHRONOUS, waits not subject to alert",
6809         "Operations NOT necessarily synchronous"
6810 };
6811 static const true_false_string tfs_nt_create_options_non_directory = {
6812         "File being created/opened must not be a directory",
6813         "File being created/opened must be a directory"
6814 };
6815 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
6816         "The client does not understand extended attributes",
6817         "The client understands extended attributes"
6818 };
6819 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
6820         "The client understands only 8.3 file names",
6821         "The client understands long file names"
6822 };
6823 static const true_false_string tfs_nt_create_options_random_access = {
6824         "The file will be accessed randomly",
6825         "The file will not be accessed randomly"
6826 };
6827 static const true_false_string tfs_nt_create_options_delete_on_close = {
6828         "The file should be deleted when it is closed",
6829         "The file should not be deleted when it is closed"
6830 };
6831
6832 static int
6833 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6834 {
6835         guint32 mask;
6836         proto_item *item = NULL;
6837         proto_tree *tree = NULL;
6838
6839         mask = tvb_get_letohl(tvb, offset);
6840
6841         if(parent_tree){
6842                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6843                         "Create Options: 0x%08x", mask);
6844                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
6845         }
6846
6847         /*
6848          * From
6849          *
6850          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6851          */
6852         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
6853                 tvb, offset, 4, mask);
6854         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
6855                 tvb, offset, 4, mask);
6856         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
6857                 tvb, offset, 4, mask);
6858         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
6859                 tvb, offset, 4, mask);
6860         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
6861                 tvb, offset, 4, mask);
6862         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
6863                 tvb, offset, 4, mask);
6864         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
6865                 tvb, offset, 4, mask);
6866         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
6867                 tvb, offset, 4, mask);
6868         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
6869                 tvb, offset, 4, mask);
6870         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
6871                 tvb, offset, 4, mask);
6872
6873         offset += 4;
6874
6875         return offset;
6876 }
6877
6878 static int
6879 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6880 {
6881         guint32 mask;
6882         proto_item *item = NULL;
6883         proto_tree *tree = NULL;
6884
6885         mask = tvb_get_letohl(tvb, offset);
6886
6887         if(parent_tree){
6888                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6889                         "Completion Filter: 0x%08x", mask);
6890                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
6891         }
6892
6893         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
6894                 tvb, offset, 4, mask);
6895         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
6896                 tvb, offset, 4, mask);
6897         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
6898                 tvb, offset, 4, mask);
6899         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
6900                 tvb, offset, 4, mask);
6901         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
6902                 tvb, offset, 4, mask);
6903         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
6904                 tvb, offset, 4, mask);
6905         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
6906                 tvb, offset, 4, mask);
6907         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
6908                 tvb, offset, 4, mask);
6909         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
6910                 tvb, offset, 4, mask);
6911         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
6912                 tvb, offset, 4, mask);
6913         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
6914                 tvb, offset, 4, mask);
6915         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
6916                 tvb, offset, 4, mask);
6917
6918         offset += 4;
6919         return offset;
6920 }
6921
6922 static int
6923 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6924 {
6925         guint8 mask;
6926         proto_item *item = NULL;
6927         proto_tree *tree = NULL;
6928
6929         mask = tvb_get_guint8(tvb, offset);
6930
6931         if(parent_tree){
6932                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6933                         "Completion Filter: 0x%02x", mask);
6934                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
6935         }
6936
6937         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
6938                 tvb, offset, 1, mask);
6939
6940         offset += 1;
6941         return offset;
6942 }
6943
6944 /*
6945  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
6946  * Native API Reference".
6947  */
6948 static const true_false_string tfs_nt_qsd_owner = {
6949         "Requesting OWNER security information",
6950         "NOT requesting owner security information",
6951 };
6952
6953 static const true_false_string tfs_nt_qsd_group = {
6954         "Requesting GROUP security information",
6955         "NOT requesting group security information",
6956 };
6957
6958 static const true_false_string tfs_nt_qsd_dacl = {
6959         "Requesting DACL security information",
6960         "NOT requesting DACL security information",
6961 };
6962
6963 static const true_false_string tfs_nt_qsd_sacl = {
6964         "Requesting SACL security information",
6965         "NOT requesting SACL security information",
6966 };
6967
6968 #define NT_QSD_OWNER    0x00000001
6969 #define NT_QSD_GROUP    0x00000002
6970 #define NT_QSD_DACL     0x00000004
6971 #define NT_QSD_SACL     0x00000008
6972
6973 static int
6974 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6975 {
6976         guint32 mask;
6977         proto_item *item = NULL;
6978         proto_tree *tree = NULL;
6979
6980         mask = tvb_get_letohl(tvb, offset);
6981
6982         if(parent_tree){
6983                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6984                         "Security Information: 0x%08x", mask);
6985                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
6986         }
6987
6988         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
6989                 tvb, offset, 4, mask);
6990         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
6991                 tvb, offset, 4, mask);
6992         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
6993                 tvb, offset, 4, mask);
6994         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
6995                 tvb, offset, 4, mask);
6996
6997         offset += 4;
6998
6999         return offset;
7000 }
7001
7002 static void
7003 free_g_string(void *arg)
7004 {
7005         g_string_free(arg, TRUE);
7006 }
7007
7008 /* Dissect a NT SID.  Label it with 'name' and return a string version of
7009    the SID in the 'sid_str' parameter which must be freed by the caller.
7010    hf_sid can be -1 if the caller doesnt care what name is used and then 
7011    "smb.sid" will be the default instead. If the caller wants a more
7012    appropriate hf field, it will just pass a FT_STRING hf field here
7013 */
7014
7015 int
7016 dissect_nt_sid(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name,
7017                char **sid_str, int hf_sid)
7018 {
7019         proto_item *item = NULL;
7020         proto_tree *tree = NULL;
7021         int old_offset = offset, sa_offset = offset;
7022         gboolean rid_present;
7023         guint rid=0;
7024         int rid_offset=0;
7025         guint8 revision;
7026         int rev_offset;
7027         guint8 num_auth;
7028         int na_offset;
7029         guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
7030         int i;
7031         GString *gstr;
7032         char sid_string[245];
7033         char *sid_name;
7034
7035         if(hf_sid==-1){
7036                 hf_sid=hf_smb_sid;
7037         }
7038
7039         /* revision of sid */
7040         revision = tvb_get_guint8(tvb, offset);
7041         rev_offset = offset;
7042         offset += 1;
7043
7044         switch(revision){
7045         case 1:
7046         case 2:  /* Not sure what the different revision numbers mean */
7047           /* number of authorities*/
7048           num_auth = tvb_get_guint8(tvb, offset);
7049           na_offset = offset;
7050           offset += 1;
7051
7052           /* XXX perhaps we should have these thing searchable?
7053              a new FT_xxx thingie? SMB is quite common!*/
7054           /* identifier authorities */
7055
7056           for(i=0;i<6;i++){
7057             auth = (auth << 8) + tvb_get_guint8(tvb, offset);
7058
7059             offset++;
7060           }
7061
7062           sa_offset = offset;
7063
7064           gstr = g_string_new("");
7065
7066           CLEANUP_PUSH(free_g_string, gstr);
7067
7068           /* sub authorities, leave RID to last */
7069           for(i=0; i < (num_auth > 4?(num_auth - 1):num_auth); i++){
7070             /*
7071              * XXX should not be letohl but native byteorder according to
7072              * Samba header files.
7073              *
7074              * However, considering that there were never any NT ports
7075              * to big-endian platforms (PowerPC and MIPS ran little-endian,
7076              * and IA-64 runs little-endian, as does x86-64), we can (?)
7077              * assume that non le byte encodings will be "uncommon"?
7078              */
7079              g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"),
7080                   tvb_get_letohl(tvb, offset));
7081              offset+=4;
7082           }
7083
7084
7085           if (num_auth > 4) {
7086             rid = tvb_get_letohl(tvb, offset);
7087             rid_present=TRUE;
7088             rid_offset=offset;
7089             offset+=4;
7090             sprintf(sid_string, "S-1-%u-%s-%u", auth, gstr->str, rid);
7091           } else {
7092             rid_present=FALSE;
7093             sprintf(sid_string, "S-1-%u-%s", auth, gstr->str);
7094           }
7095
7096           sid_name=NULL;
7097           if(sid_name_snooping){
7098             sid_name=find_sid_name(sid_string);
7099           }
7100
7101           if(parent_tree){
7102             if(sid_name){
7103               item = proto_tree_add_string_format(parent_tree, hf_sid, tvb, old_offset, offset-old_offset, sid_string, "%s: %s (%s)", name, sid_string, sid_name);
7104             } else {
7105               item = proto_tree_add_string_format(parent_tree, hf_sid, tvb, old_offset, offset-old_offset, sid_string, "%s: %s", name, sid_string);
7106             }
7107             tree = proto_item_add_subtree(item, ett_smb_sid);
7108           }
7109
7110           proto_tree_add_item(tree, hf_smb_sid_revision, tvb, rev_offset, 1, TRUE);
7111           proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, na_offset, 1, TRUE);
7112           proto_tree_add_text(tree, tvb, na_offset+1, 6, "Authority: %u", auth);
7113           proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
7114
7115           if(rid_present){
7116             proto_tree_add_text(tree, tvb, rid_offset, 4, "RID: %u", rid);
7117           }
7118
7119           if(sid_str){
7120             if(sid_name){
7121               *sid_str = g_strdup_printf("%s (%s)", sid_string, sid_name);
7122             } else {
7123               *sid_str = g_strdup(sid_string);
7124             }
7125           }
7126
7127           CLEANUP_CALL_AND_POP;
7128         }
7129
7130
7131         return offset;
7132 }
7133
7134
7135 static const value_string ace_type_vals[] = {
7136   { 0, "Access Allowed"},
7137   { 1, "Access Denied"},
7138   { 2, "System Audit"},
7139   { 3, "System Alarm"},
7140   { 0, NULL}
7141 };
7142 static const true_false_string tfs_ace_flags_object_inherit = {
7143   "Subordinate files will inherit this ACE",
7144   "Subordinate files will not inherit this ACE"
7145 };
7146 static const true_false_string tfs_ace_flags_container_inherit = {
7147   "Subordinate containers will inherit this ACE",
7148   "Subordinate containers will not inherit this ACE"
7149 };
7150 static const true_false_string tfs_ace_flags_non_propagate_inherit = {
7151   "Subordinate object will not propagate the inherited ACE further",
7152   "Subordinate object will propagate the inherited ACE further"
7153 };
7154 static const true_false_string tfs_ace_flags_inherit_only = {
7155   "This ACE does not apply to the current object",
7156   "This ACE applies to the current object"
7157 };
7158 static const true_false_string tfs_ace_flags_inherited_ace = {
7159   "This ACE was inherited from its parent object",
7160   "This ACE was not inherited from its parent object"
7161 };
7162 static const true_false_string tfs_ace_flags_successful_access = {
7163   "Successful accesses will be audited",
7164   "Successful accesses will not be audited"
7165 };
7166 static const true_false_string tfs_ace_flags_failed_access = {
7167   "Failed accesses will be audited",
7168   "Failed accesses will not be audited"
7169 };
7170
7171 #define APPEND_ACE_TEXT(flag, item, string) \
7172         if(flag){                                                       \
7173                 if(item)                                                \
7174                         proto_item_append_text(item, string, sep);      \
7175                 sep = ", ";                                             \
7176         }
7177
7178 static int
7179 dissect_nt_v2_ace_flags(tvbuff_t *tvb, int offset, proto_tree *parent_tree,
7180                         guint8 *data)
7181 {
7182         proto_item *item = NULL;
7183         proto_tree *tree = NULL;
7184         guint8 mask;
7185         char *sep = " ";
7186
7187         mask = tvb_get_guint8(tvb, offset);
7188
7189         if (data)
7190                 *data = mask;
7191
7192
7193         if(parent_tree){
7194                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7195                                            "NT ACE Flags: 0x%02x", mask);
7196                 tree = proto_item_add_subtree(item, ett_smb_ace_flags);
7197         }
7198
7199         proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
7200                        tvb, offset, 1, mask);
7201         APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
7202
7203         proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
7204                        tvb, offset, 1, mask);
7205         APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
7206
7207         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
7208                        tvb, offset, 1, mask);
7209         APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
7210
7211         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
7212                        tvb, offset, 1, mask);
7213         APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
7214
7215         proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
7216                        tvb, offset, 1, mask);
7217         APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
7218
7219         proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
7220                        tvb, offset, 1, mask);
7221         APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
7222
7223         proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
7224                        tvb, offset, 1, mask);
7225         APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
7226
7227
7228         offset += 1;
7229         return offset;
7230 }
7231
7232 /* Dissect an access mask.  All this stuff is kind of explained at MSDN:
7233
7234 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/windows_2000_windows_nt_access_mask_format.asp
7235
7236 */
7237
7238 static gint ett_nt_access_mask = -1;
7239 static gint ett_nt_access_mask_generic = -1;
7240 static gint ett_nt_access_mask_standard = -1;
7241 static gint ett_nt_access_mask_specific = -1;
7242
7243 static int hf_access_sacl = -1;
7244 static int hf_access_maximum_allowed = -1;
7245 static int hf_access_generic_read = -1;
7246 static int hf_access_generic_write = -1;
7247 static int hf_access_generic_execute = -1;
7248 static int hf_access_generic_all = -1;
7249 static int hf_access_standard_delete = -1;
7250 static int hf_access_standard_read_control = -1;
7251 static int hf_access_standard_synchronise = -1;
7252 static int hf_access_standard_write_dac = -1;
7253 static int hf_access_standard_write_owner = -1;
7254 static int hf_access_specific_15 = -1;
7255 static int hf_access_specific_14 = -1;
7256 static int hf_access_specific_13 = -1;
7257 static int hf_access_specific_12 = -1;
7258 static int hf_access_specific_11 = -1;
7259 static int hf_access_specific_10 = -1;
7260 static int hf_access_specific_9 = -1;
7261 static int hf_access_specific_8 = -1;
7262 static int hf_access_specific_7 = -1;
7263 static int hf_access_specific_6 = -1;
7264 static int hf_access_specific_5 = -1;
7265 static int hf_access_specific_4 = -1;
7266 static int hf_access_specific_3 = -1;
7267 static int hf_access_specific_2 = -1;
7268 static int hf_access_specific_1 = -1;
7269 static int hf_access_specific_0 = -1;
7270
7271 /* Map generic permissions to specific permissions */
7272
7273 static void map_generic_access(guint32 *access_mask, 
7274                                struct generic_mapping *mapping)
7275 {
7276         if (*access_mask & GENERIC_READ_ACCESS) {
7277                 *access_mask &= ~GENERIC_READ_ACCESS;
7278                 *access_mask |= mapping->generic_read;
7279         }
7280
7281         if (*access_mask & GENERIC_WRITE_ACCESS) {
7282                 *access_mask &= ~GENERIC_WRITE_ACCESS;
7283                 *access_mask |= mapping->generic_write;
7284         }
7285
7286         if (*access_mask & GENERIC_EXECUTE_ACCESS) {
7287                 *access_mask &= ~GENERIC_EXECUTE_ACCESS;
7288                 *access_mask |= mapping->generic_execute;
7289         }
7290
7291         if (*access_mask & GENERIC_ALL_ACCESS) {
7292                 *access_mask &= ~GENERIC_ALL_ACCESS;
7293                 *access_mask |= mapping->generic_all;
7294         }
7295 }
7296
7297 /* Map standard permissions to specific permissions */
7298
7299 static void map_standard_access(guint32 *access_mask,
7300                                 struct standard_mapping *mapping)
7301 {
7302         if (*access_mask & READ_CONTROL_ACCESS) {
7303                 *access_mask &= ~READ_CONTROL_ACCESS;
7304                 *access_mask |= mapping->std_read;
7305         }
7306
7307         if (*access_mask & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|
7308                             SYNCHRONIZE_ACCESS)) {
7309                 *access_mask &= ~(DELETE_ACCESS|WRITE_DAC_ACCESS|
7310                                   WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS);
7311                 *access_mask |= mapping->std_all;
7312         }
7313
7314 }
7315
7316 int
7317 dissect_nt_access_mask(tvbuff_t *tvb, gint offset, packet_info *pinfo,
7318                        proto_tree *tree, char *drep, int hfindex,
7319                        struct access_mask_info *ami)
7320 {
7321         proto_item *item;
7322         proto_tree *subtree, *generic_tree, *standard_tree, *specific_tree;
7323         guint32 access;
7324
7325         if (drep != NULL) {
7326                 /*
7327                  * Called from a DCE RPC protocol dissector, for a
7328                  * protocol where a 32-bit NDR integer contains
7329                  * an NT access mask; extract the access mask
7330                  * with an NDR call.
7331                  */
7332                 offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
7333                                             hfindex, &access);
7334         } else {
7335                 /*
7336                  * Called from SMB, where the access mask is just a
7337                  * 4-byte little-endian quantity with no special
7338                  * NDR alignment requirement; extract it with
7339                  * "tvb_get_letohl()".
7340                  */
7341                 access = tvb_get_letohl(tvb, offset);
7342                 offset += 4;
7343         }
7344
7345         item = proto_tree_add_uint(tree, hfindex, tvb, offset - 4, 4, access);
7346
7347         subtree = proto_item_add_subtree(item, ett_nt_access_mask);
7348
7349         /* Generic access rights */
7350
7351         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7352                                    "Generic rights: 0x%08x",
7353                                    access & GENERIC_RIGHTS_MASK);
7354
7355         generic_tree = proto_item_add_subtree(
7356                 item, ett_nt_access_mask_generic);
7357
7358         proto_tree_add_boolean(
7359                 generic_tree, hf_access_generic_read, tvb, offset - 4, 4,
7360                 access);
7361
7362         proto_tree_add_boolean(
7363                 generic_tree, hf_access_generic_write, tvb, offset - 4, 4,
7364                 access);
7365
7366         proto_tree_add_boolean(
7367                 generic_tree, hf_access_generic_execute, tvb, offset - 4, 4,
7368                 access);
7369
7370         proto_tree_add_boolean(
7371                 generic_tree, hf_access_generic_all, tvb, offset - 4, 4,
7372                 access);
7373
7374         /* Reserved (??) */
7375
7376         proto_tree_add_boolean(
7377                 subtree, hf_access_maximum_allowed, tvb, offset - 4, 4,
7378                 access);
7379
7380         /* Access system security */
7381
7382         proto_tree_add_boolean(
7383                 subtree, hf_access_sacl, tvb, offset - 4, 4,
7384                 access);
7385
7386         /* Standard access rights */
7387
7388         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7389                                    "Standard rights: 0x%08x",
7390                                    access & STANDARD_RIGHTS_MASK);
7391
7392         standard_tree = proto_item_add_subtree(
7393                 item, ett_nt_access_mask_standard);
7394
7395         proto_tree_add_boolean(
7396                 standard_tree, hf_access_standard_synchronise, tvb, 
7397                 offset - 4, 4, access);
7398
7399         proto_tree_add_boolean(
7400                 standard_tree, hf_access_standard_write_owner, tvb, 
7401                 offset - 4, 4, access);
7402
7403         proto_tree_add_boolean(
7404                 standard_tree, hf_access_standard_write_dac, tvb, 
7405                 offset - 4, 4, access);
7406
7407         proto_tree_add_boolean(
7408                 standard_tree, hf_access_standard_read_control, tvb, 
7409                 offset - 4, 4, access);
7410
7411         proto_tree_add_boolean(
7412                 standard_tree, hf_access_standard_delete, tvb, offset - 4, 4,
7413                 access);
7414
7415         /* Specific access rights.  Call the specific_rights_fn
7416            pointer if we have one, otherwise just display bits 0-15 in
7417            boring fashion. */
7418
7419         if (ami && ami->specific_rights_name)
7420                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7421                                            "%s specific rights: 0x%08x",
7422                                            ami->specific_rights_name,
7423                                            access & SPECIFIC_RIGHTS_MASK);
7424         else
7425                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7426                                            "Specific rights: 0x%08x",
7427                                            access & SPECIFIC_RIGHTS_MASK);
7428
7429         specific_tree = proto_item_add_subtree(
7430                 item, ett_nt_access_mask_specific);
7431
7432         if (ami && ami->specific_rights_fn) {
7433                 guint32 mapped_access = access;
7434                 proto_tree *specific_mapped;
7435
7436                 specific_mapped = proto_item_add_subtree(
7437                         item, ett_nt_access_mask_specific);
7438
7439                 ami->specific_rights_fn(
7440                         tvb, offset - 4, specific_tree, access);
7441
7442                 if (ami->generic_mapping)
7443                         map_generic_access(&access, ami->generic_mapping);
7444                 
7445                 if (ami->standard_mapping)
7446                         map_standard_access(&access, ami->standard_mapping);
7447
7448                 if (access != mapped_access) {
7449                         ami->specific_rights_fn(
7450                                 tvb, offset - 4, specific_mapped, 
7451                                 mapped_access);
7452                 }
7453                 
7454                 return offset;
7455         }
7456
7457         proto_tree_add_boolean(
7458                 specific_tree, hf_access_specific_15, tvb, offset - 4, 4,
7459                 access);
7460
7461         proto_tree_add_boolean(
7462                 specific_tree, hf_access_specific_14, tvb, offset - 4, 4,
7463                 access);
7464
7465         proto_tree_add_boolean(
7466                 specific_tree, hf_access_specific_13, tvb, offset - 4, 4,
7467                 access);
7468
7469         proto_tree_add_boolean(
7470                 specific_tree, hf_access_specific_12, tvb, offset - 4, 4,
7471                 access);
7472
7473         proto_tree_add_boolean(
7474                 specific_tree, hf_access_specific_11, tvb, offset - 4, 4,
7475                 access);
7476
7477         proto_tree_add_boolean(
7478                 specific_tree, hf_access_specific_10, tvb, offset - 4, 4,
7479                 access);
7480
7481         proto_tree_add_boolean(
7482                 specific_tree, hf_access_specific_9, tvb, offset - 4, 4,
7483                 access);
7484
7485         proto_tree_add_boolean(
7486                 specific_tree, hf_access_specific_8, tvb, offset - 4, 4,
7487                 access);
7488
7489         proto_tree_add_boolean(
7490                 specific_tree, hf_access_specific_7, tvb, offset - 4, 4,
7491                 access);
7492
7493         proto_tree_add_boolean(
7494                 specific_tree, hf_access_specific_6, tvb, offset - 4, 4,
7495                 access);
7496
7497         proto_tree_add_boolean(
7498                 specific_tree, hf_access_specific_5, tvb, offset - 4, 4,
7499                 access);
7500
7501         proto_tree_add_boolean(
7502                 specific_tree, hf_access_specific_4, tvb, offset - 4, 4,
7503                 access);
7504
7505         proto_tree_add_boolean(
7506                 specific_tree, hf_access_specific_3, tvb, offset - 4, 4,
7507                 access);
7508
7509         proto_tree_add_boolean(
7510                 specific_tree, hf_access_specific_2, tvb, offset - 4, 4,
7511                 access);
7512
7513         proto_tree_add_boolean(
7514                 specific_tree, hf_access_specific_1, tvb, offset - 4, 4,
7515                 access);
7516
7517         proto_tree_add_boolean(
7518                 specific_tree, hf_access_specific_0, tvb, offset - 4, 4,
7519                 access);
7520
7521         return offset;
7522 }
7523
7524 static int hf_smb_access_mask = -1;
7525
7526 static int
7527 dissect_nt_v2_ace(tvbuff_t *tvb, int offset, packet_info *pinfo,
7528                   proto_tree *parent_tree, char *drep,
7529                   struct access_mask_info *ami)
7530 {
7531         proto_item *item = NULL;
7532         proto_tree *tree = NULL;
7533         int old_offset = offset;
7534         guint16 size;
7535         char *sid_str = NULL;
7536         guint8 type;
7537         guint8 flags;
7538
7539         if(parent_tree){
7540                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7541                                            "NT ACE: ");
7542                 tree = proto_item_add_subtree(item, ett_smb_ace);
7543         }
7544
7545         /* type */
7546         type = tvb_get_guint8(tvb, offset);
7547         proto_tree_add_uint(tree, hf_smb_ace_type, tvb, offset, 1, type);
7548         offset += 1;
7549
7550         /* flags */
7551         offset = dissect_nt_v2_ace_flags(tvb, offset, tree, &flags);
7552
7553         /* size */
7554         size = tvb_get_letohs(tvb, offset);
7555         proto_tree_add_uint(tree, hf_smb_ace_size, tvb, offset, 2, size);
7556         offset += 2;
7557
7558         /* access mask */
7559         offset = dissect_nt_access_mask(
7560                 tvb, offset, pinfo, tree, drep, hf_smb_access_mask, ami);
7561
7562         /* SID */
7563         offset = dissect_nt_sid(tvb, offset, tree, "ACE", &sid_str, -1);
7564
7565         if (item)
7566                 proto_item_append_text(
7567                         item, "%s, flags 0x%02x, %s", sid_str, flags,
7568                         val_to_str(type, ace_type_vals, "Unknown ACE type (0x%02x)"));
7569
7570         g_free(sid_str);
7571
7572         proto_item_set_len(item, offset-old_offset);
7573
7574         /* Sometimes there is some spare space at the end of the ACE so use
7575            the size field to work out where the end is. */
7576
7577         return old_offset + size;
7578 }
7579
7580 static int
7581 dissect_nt_acl(tvbuff_t *tvb, int offset, packet_info *pinfo,
7582                proto_tree *parent_tree, char *drep, char *name,
7583                struct access_mask_info *ami)
7584 {
7585         proto_item *item = NULL;
7586         proto_tree *tree = NULL;
7587         int old_offset = offset;
7588         guint16 revision;
7589         guint32 num_aces;
7590
7591         if(parent_tree){
7592                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7593                                            "NT %s ACL", name);
7594                 tree = proto_item_add_subtree(item, ett_smb_acl);
7595         }
7596
7597         /* revision */
7598         revision = tvb_get_letohs(tvb, offset);
7599         proto_tree_add_uint(tree, hf_smb_acl_revision,
7600                 tvb, offset, 2, revision);
7601         offset += 2;
7602
7603         switch(revision){
7604         case 2:  /* only version we will ever see of this structure?*/
7605         case 3:
7606           /* size */
7607           proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
7608           offset += 2;
7609
7610           /* number of ace structures */
7611           num_aces = tvb_get_letohl(tvb, offset);
7612           proto_tree_add_uint(tree, hf_smb_acl_num_aces,
7613                               tvb, offset, 4, num_aces);
7614           offset += 4;
7615
7616           while(num_aces--){
7617             offset=dissect_nt_v2_ace(
7618                     tvb, offset, pinfo, tree, drep, ami);
7619           }
7620         }
7621
7622         proto_item_set_len(item, offset-old_offset);
7623         return offset;
7624 }
7625
7626 static const true_false_string tfs_sec_desc_type_owner_defaulted = {
7627   "OWNER is DEFAULTED",
7628   "Owner is NOT defaulted"
7629 };
7630 static const true_false_string tfs_sec_desc_type_group_defaulted = {
7631   "GROUP is DEFAULTED",
7632   "Group is NOT defaulted"
7633 };
7634 static const true_false_string tfs_sec_desc_type_dacl_present = {
7635   "DACL is PRESENT",
7636   "DACL is NOT present"
7637 };
7638 static const true_false_string tfs_sec_desc_type_dacl_defaulted = {
7639   "DACL is DEFAULTED",
7640   "DACL is NOT defaulted"
7641 };
7642 static const true_false_string tfs_sec_desc_type_sacl_present = {
7643   "SACL is PRESENT",
7644   "SACL is NOT present"
7645 };
7646 static const true_false_string tfs_sec_desc_type_sacl_defaulted = {
7647   "SACL is DEFAULTED",
7648   "SACL is NOT defaulted"
7649 };
7650 static const true_false_string tfs_sec_desc_type_dacl_auto_inherit_req = {
7651   "DACL has AUTO INHERIT REQUIRED",
7652   "DACL does NOT require auto inherit"
7653 };
7654 static const true_false_string tfs_sec_desc_type_sacl_auto_inherit_req = {
7655   "SACL has AUTO INHERIT REQUIRED",
7656   "SACL does NOT require auto inherit"
7657 };
7658 static const true_false_string tfs_sec_desc_type_dacl_auto_inherited = {
7659   "DACL is AUTO INHERITED",
7660   "DACL is NOT auto inherited"
7661 };
7662 static const true_false_string tfs_sec_desc_type_sacl_auto_inherited = {
7663   "SACL is AUTO INHERITED",
7664   "SACL is NOT auto inherited"
7665 };
7666 static const true_false_string tfs_sec_desc_type_dacl_protected = {
7667   "The DACL is PROTECTED",
7668   "The DACL is NOT protected"
7669 };
7670 static const true_false_string tfs_sec_desc_type_sacl_protected = {
7671   "The SACL is PROTECTED",
7672   "The SACL is NOT protected"
7673 };
7674 static const true_false_string tfs_sec_desc_type_self_relative = {
7675   "This SecDesc is SELF RELATIVE",
7676   "This SecDesc is NOT self relative"
7677 };
7678
7679
7680 static int
7681 dissect_nt_sec_desc_type(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7682 {
7683         proto_item *item = NULL;
7684         proto_tree *tree = NULL;
7685         guint16 mask;
7686
7687         mask = tvb_get_letohs(tvb, offset);
7688         if(parent_tree){
7689                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7690                                            "Type: 0x%04x", mask);
7691                 tree = proto_item_add_subtree(item, ett_smb_sec_desc_type);
7692         }
7693
7694         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_self_relative,
7695                                tvb, offset, 2, mask);
7696         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_protected,
7697                                tvb, offset, 2, mask);
7698         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_protected,
7699                                tvb, offset, 2, mask);
7700         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherited,
7701                                tvb, offset, 2, mask);
7702         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherited,
7703                                tvb, offset, 2, mask);
7704         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherit_req,
7705                                tvb, offset, 2, mask);
7706         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherit_req,
7707                                tvb, offset, 2, mask);
7708         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_defaulted,
7709                                tvb, offset, 2, mask);
7710         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_present,
7711                                tvb, offset, 2, mask);
7712         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_defaulted,
7713                                tvb, offset, 2, mask);
7714         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_present,
7715                                tvb, offset, 2, mask);
7716         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_group_defaulted,
7717                                tvb, offset, 2, mask);
7718         proto_tree_add_boolean(tree, hf_smb_sec_desc_type_owner_defaulted,
7719                                tvb, offset, 2, mask);
7720
7721
7722         offset += 2;
7723         return offset;
7724 }
7725
7726 int
7727 dissect_nt_sec_desc(tvbuff_t *tvb, int offset, packet_info *pinfo,
7728                     proto_tree *parent_tree, char *drep, int len, 
7729                     struct access_mask_info *ami)
7730 {
7731         proto_item *item = NULL;
7732         proto_tree *tree = NULL;
7733         guint8 revision;
7734         int old_offset = offset;
7735         guint32 owner_sid_offset;
7736         guint32 group_sid_offset;
7737         guint32 sacl_offset;
7738         guint32 dacl_offset;
7739
7740         if(parent_tree){
7741                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7742                                            "NT Security Descriptor");
7743                 tree = proto_item_add_subtree(item, ett_smb_sec_desc);
7744         }
7745
7746         /* revision */
7747         revision = tvb_get_guint8(tvb, offset);
7748         proto_tree_add_uint(tree, hf_smb_sec_desc_revision,
7749                 tvb, offset, 1, revision);
7750         offset += 1;
7751
7752         /* next byte should be zero, for now just ignore it */
7753         offset += 1;
7754
7755
7756         switch(revision){
7757         case 1:  /* only version we will ever see of this structure?*/
7758           /* type */
7759           offset = dissect_nt_sec_desc_type(tvb, offset, tree);
7760
7761           /* offset to owner sid */
7762           owner_sid_offset = tvb_get_letohl(tvb, offset);
7763           proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %u", owner_sid_offset);
7764           offset += 4;
7765
7766           /* offset to group sid */
7767           group_sid_offset = tvb_get_letohl(tvb, offset);
7768           proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %u", group_sid_offset);
7769           offset += 4;
7770
7771           /* offset to sacl */
7772           sacl_offset = tvb_get_letohl(tvb, offset);
7773           proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %u", sacl_offset);
7774           offset += 4;
7775
7776           /* offset to dacl */
7777           dacl_offset = tvb_get_letohl(tvb, offset);
7778           proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %u", dacl_offset);
7779           offset += 4;
7780
7781           /*owner SID*/
7782           if(owner_sid_offset){
7783             if (len == -1)
7784               offset = dissect_nt_sid(tvb, offset, tree, "Owner", NULL, -1);
7785             else
7786               dissect_nt_sid(
7787                       tvb, old_offset+owner_sid_offset, tree, "Owner", NULL, -1);
7788           }
7789
7790           /*group SID*/
7791           if(group_sid_offset){
7792             dissect_nt_sid(
7793                     tvb, old_offset+group_sid_offset, tree, "Group", NULL, -1);
7794           }
7795
7796           /* sacl */
7797           if(sacl_offset){
7798             dissect_nt_acl(tvb, old_offset+sacl_offset, pinfo, tree, 
7799                            drep, "System (SACL)", ami);
7800           }
7801
7802           /* dacl */
7803           if(dacl_offset){
7804             dissect_nt_acl(tvb, old_offset+dacl_offset, pinfo, tree, 
7805                            drep, "User (DACL)", ami);
7806           }
7807
7808         }
7809
7810         return offset+len;
7811 }
7812
7813 static int
7814 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
7815 {
7816         int old_offset, old_sid_offset;
7817         guint32 qsize;
7818
7819         do {
7820                 old_offset=offset;
7821
7822                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7823                 qsize=tvb_get_letohl(tvb, offset);
7824                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
7825                 COUNT_BYTES_TRANS_SUBR(4);
7826
7827                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7828                 /* length of SID */
7829                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7830                 COUNT_BYTES_TRANS_SUBR(4);
7831
7832                 /* 16 unknown bytes */
7833                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7834                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7835                             offset, 8, TRUE);
7836                 COUNT_BYTES_TRANS_SUBR(8);
7837
7838                 /* number of bytes for used quota */
7839                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7840                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
7841                 COUNT_BYTES_TRANS_SUBR(8);
7842
7843                 /* number of bytes for quota warning */
7844                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7845                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
7846                 COUNT_BYTES_TRANS_SUBR(8);
7847
7848                 /* number of bytes for quota limit */
7849                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7850                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
7851                 COUNT_BYTES_TRANS_SUBR(8);
7852
7853                 /* SID of the user */
7854                 old_sid_offset=offset;
7855                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
7856                 *bcp -= (offset-old_sid_offset);
7857
7858                 if(qsize){
7859                         offset = old_offset+qsize;
7860                 }
7861         }while(qsize);
7862
7863
7864         return offset;
7865 }
7866
7867
7868 static int
7869 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
7870 {
7871         proto_item *item = NULL;
7872         proto_tree *tree = NULL;
7873         smb_info_t *si;
7874         int old_offset = offset;
7875         guint16 bcp=bc; /* XXX fixme */
7876
7877         si = (smb_info_t *)pinfo->private_data;
7878
7879         if(parent_tree){
7880                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
7881                                 "%s Data",
7882                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7883                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7884         }
7885
7886         switch(ntd->subcmd){
7887         case NT_TRANS_CREATE:
7888                 /* security descriptor */
7889                 if(ntd->sd_len){
7890                         offset = dissect_nt_sec_desc(
7891                                 tvb, offset, pinfo, tree, NULL, ntd->sd_len, 
7892                                 NULL);
7893                 }
7894
7895                 /* extended attributes */
7896                 if(ntd->ea_len){
7897                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
7898                         offset += ntd->ea_len;
7899                 }
7900
7901                 break;
7902         case NT_TRANS_IOCTL:
7903                 /* ioctl data */
7904                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
7905                 offset += bc;
7906
7907                 break;
7908         case NT_TRANS_SSD:
7909                 offset = dissect_nt_sec_desc(
7910                         tvb, offset, pinfo, tree, NULL, bc, NULL);
7911                 break;
7912         case NT_TRANS_NOTIFY:
7913                 break;
7914         case NT_TRANS_RENAME:
7915                 /* XXX not documented */
7916                 break;
7917         case NT_TRANS_QSD:
7918                 break;
7919         case NT_TRANS_GET_USER_QUOTA:
7920                 /* unknown 4 bytes */
7921                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7922                             offset, 4, TRUE);
7923                 offset += 4;
7924
7925                 /* length of SID */
7926                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7927                 offset +=4;
7928
7929                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
7930                 break;
7931         case NT_TRANS_SET_USER_QUOTA:
7932                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
7933                 break;
7934         }
7935
7936         /* ooops there were data we didnt know how to process */
7937         if((offset-old_offset) < bc){
7938                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
7939                     bc - (offset-old_offset), TRUE);
7940                 offset += bc - (offset-old_offset);
7941         }
7942
7943         return offset;
7944 }
7945
7946 static int
7947 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)
7948 {
7949         proto_item *item = NULL;
7950         proto_tree *tree = NULL;
7951         smb_info_t *si;
7952         guint32 fn_len;
7953         const char *fn;
7954
7955         si = (smb_info_t *)pinfo->private_data;
7956
7957         if(parent_tree){
7958                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7959                                 "%s Parameters",
7960                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7961                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7962         }
7963
7964         switch(ntd->subcmd){
7965         case NT_TRANS_CREATE:
7966                 /* Create flags */
7967                 offset = dissect_nt_create_bits(tvb, tree, offset);
7968                 bc -= 4;
7969
7970                 /* root directory fid */
7971                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
7972                 COUNT_BYTES(4);
7973
7974                 /* nt access mask */
7975                 offset = dissect_smb_access_mask(tvb, tree, offset);
7976                 bc -= 4;
7977
7978                 /* allocation size */
7979                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7980                 COUNT_BYTES(8);
7981
7982                 /* Extended File Attributes */
7983                 offset = dissect_file_ext_attr(tvb, tree, offset);
7984                 bc -= 4;
7985
7986                 /* share access */
7987                 offset = dissect_nt_share_access(tvb, tree, offset);
7988                 bc -= 4;
7989
7990                 /* create disposition */
7991                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
7992                 COUNT_BYTES(4);
7993
7994                 /* create options */
7995                 offset = dissect_nt_create_options(tvb, tree, offset);
7996                 bc -= 4;
7997
7998                 /* sd length */
7999                 ntd->sd_len = tvb_get_letohl(tvb, offset);
8000                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
8001                 COUNT_BYTES(4);
8002
8003                 /* ea length */
8004                 ntd->ea_len = tvb_get_letohl(tvb, offset);
8005                 proto_tree_add_uint(tree, hf_smb_ea_list_length, tvb, offset, 4, ntd->ea_len);
8006                 COUNT_BYTES(4);
8007
8008                 /* file name len */
8009                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
8010                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8011                 COUNT_BYTES(4);
8012
8013                 /* impersonation level */
8014                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8015                 COUNT_BYTES(4);
8016
8017                 /* security flags */
8018                 offset = dissect_nt_security_flags(tvb, tree, offset);
8019                 bc -= 1;
8020
8021                 /* file name */
8022                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8023                 if (fn != NULL) {
8024                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8025                                 fn);
8026                         COUNT_BYTES(fn_len);
8027                 }
8028
8029                 break;
8030         case NT_TRANS_IOCTL:
8031                 break;
8032         case NT_TRANS_SSD: {
8033                 guint16 fid;
8034
8035                 /* fid */
8036                 fid = tvb_get_letohs(tvb, offset);
8037                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8038                 offset += 2;
8039
8040                 /* 2 reserved bytes */
8041                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8042                 offset += 2;
8043
8044                 /* security information */
8045                 offset = dissect_security_information_mask(tvb, tree, offset);
8046                 break;
8047         }
8048         case NT_TRANS_NOTIFY:
8049                 break;
8050         case NT_TRANS_RENAME:
8051                 /* XXX not documented */
8052                 break;
8053         case NT_TRANS_QSD: {
8054                 guint16 fid;
8055
8056                 /* fid */
8057                 fid = tvb_get_letohs(tvb, offset);
8058                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8059                 offset += 2;
8060
8061                 /* 2 reserved bytes */
8062                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8063                 offset += 2;
8064
8065                 /* security information */
8066                 offset = dissect_security_information_mask(tvb, tree, offset);
8067                 break;
8068         }
8069         case NT_TRANS_GET_USER_QUOTA:
8070                 /* not decoded yet */
8071                 break;
8072         case NT_TRANS_SET_USER_QUOTA:
8073                 /* not decoded yet */
8074                 break;
8075         }
8076
8077         return offset;
8078 }
8079
8080 static int
8081 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
8082 {
8083         proto_item *item = NULL;
8084         proto_tree *tree = NULL;
8085         smb_info_t *si;
8086         int old_offset = offset;
8087
8088         si = (smb_info_t *)pinfo->private_data;
8089
8090         if(parent_tree){
8091                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8092                                 "%s Setup",
8093                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8094                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8095         }
8096
8097         switch(ntd->subcmd){
8098         case NT_TRANS_CREATE:
8099                 break;
8100         case NT_TRANS_IOCTL: {
8101                 guint16 fid;
8102
8103                 /* function code */
8104                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
8105                 offset += 4;
8106
8107                 /* fid */
8108                 fid = tvb_get_letohs(tvb, offset);
8109                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8110                 offset += 2;
8111
8112                 /* isfsctl */
8113                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
8114                 offset += 1;
8115
8116                 /* isflags */
8117                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
8118
8119                 break;
8120         }
8121         case NT_TRANS_SSD:
8122                 break;
8123         case NT_TRANS_NOTIFY: {
8124                 guint16 fid;
8125
8126                 /* completion filter */
8127                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
8128
8129                 /* fid */
8130                 fid = tvb_get_letohs(tvb, offset);
8131                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8132                 offset += 2;
8133
8134                 /* watch tree */
8135                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
8136                 offset += 1;
8137
8138                 /* reserved byte */
8139                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8140                 offset += 1;
8141
8142                 break;
8143         }
8144         case NT_TRANS_RENAME:
8145                 /* XXX not documented */
8146                 break;
8147         case NT_TRANS_QSD:
8148                 break;
8149         case NT_TRANS_GET_USER_QUOTA:
8150                 /* not decoded yet */
8151                 break;
8152         case NT_TRANS_SET_USER_QUOTA:
8153                 /* not decoded yet */
8154                 break;
8155         }
8156
8157         return old_offset+len;
8158 }
8159
8160
8161 static int
8162 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8163 {
8164         guint8 wc, sc;
8165         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
8166         smb_info_t *si;
8167         smb_saved_info_t *sip;
8168         int subcmd;
8169         nt_trans_data ntd;
8170         guint16 bc;
8171         int padcnt;
8172         smb_nt_transact_info_t *nti;
8173
8174         si = (smb_info_t *)pinfo->private_data;
8175         sip = si->sip;
8176
8177         WORD_COUNT;
8178
8179         if(wc>=19){
8180                 /* primary request */
8181                 /* max setup count */
8182                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
8183                 offset += 1;
8184
8185                 /* 2 reserved bytes */
8186                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8187                 offset += 2;
8188         } else {
8189                 /* secondary request */
8190                 /* 3 reserved bytes */
8191                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8192                 offset += 3;
8193         }
8194
8195
8196         /* total param count */
8197         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
8198         offset += 4;
8199
8200         /* total data count */
8201         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
8202         offset += 4;
8203
8204         if(wc>=19){
8205                 /* primary request */
8206                 /* max param count */
8207                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
8208                 offset += 4;
8209
8210                 /* max data count */
8211                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
8212                 offset += 4;
8213         }
8214
8215         /* param count */
8216         pc = tvb_get_letohl(tvb, offset);
8217         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8218         offset += 4;
8219
8220         /* param offset */
8221         po = tvb_get_letohl(tvb, offset);
8222         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8223         offset += 4;
8224
8225         /* param displacement */
8226         if(wc>=19){
8227                 /* primary request*/
8228                 pd = 0;
8229         } else {
8230                 /* secondary request */
8231                 pd = tvb_get_letohl(tvb, offset);
8232                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8233                 offset += 4;
8234         }
8235
8236         /* data count */
8237         dc = tvb_get_letohl(tvb, offset);
8238         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8239         offset += 4;
8240
8241         /* data offset */
8242         od = tvb_get_letohl(tvb, offset);
8243         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8244         offset += 4;
8245
8246         /* data displacement */
8247         if(wc>=19){
8248                 /* primary request */
8249                 dd = 0;
8250         } else {
8251                 /* secondary request */
8252                 dd = tvb_get_letohl(tvb, offset);
8253                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8254                 offset += 4;
8255         }
8256
8257         /* setup count */
8258         if(wc>=19){
8259                 /* primary request */
8260                 sc = tvb_get_guint8(tvb, offset);
8261                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8262                 offset += 1;
8263         } else {
8264                 /* secondary request */
8265                 sc = 0;
8266         }
8267
8268         /* function */
8269         if(wc>=19){
8270                 /* primary request */
8271                 subcmd = tvb_get_letohs(tvb, offset);
8272                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
8273                 if(check_col(pinfo->cinfo, COL_INFO)){
8274                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8275                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
8276                 }
8277                 ntd.subcmd = subcmd;
8278                 if (!si->unidir) {
8279                         if(!pinfo->fd->flags.visited){
8280                                 /*
8281                                  * Allocate a new smb_nt_transact_info_t
8282                                  * structure.
8283                                  */
8284                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
8285                                 nti->subcmd = subcmd;
8286                                 sip->extra_info = nti;
8287                         }
8288                 }
8289         } else {
8290                 /* secondary request */
8291                 if(check_col(pinfo->cinfo, COL_INFO)){
8292                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
8293                 }
8294         }
8295         offset += 2;
8296
8297         /* this is a padding byte */
8298         if(offset%1){
8299                 /* pad byte */
8300                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
8301                 offset += 1;
8302         }
8303
8304         /* if there were any setup bytes, decode them */
8305         if(sc){
8306                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
8307                 offset += sc*2;
8308         }
8309
8310         BYTE_COUNT;
8311
8312         /* parameters */
8313         if(po>(guint32)offset){
8314                 /* We have some initial padding bytes.
8315                 */
8316                 padcnt = po-offset;
8317                 if (padcnt > bc)
8318                         padcnt = bc;
8319                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8320                 COUNT_BYTES(padcnt);
8321         }
8322         if(pc){
8323                 CHECK_BYTE_COUNT(pc);
8324                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
8325                 COUNT_BYTES(pc);
8326         }
8327
8328         /* data */
8329         if(od>(guint32)offset){
8330                 /* We have some initial padding bytes.
8331                 */
8332                 padcnt = od-offset;
8333                 if (padcnt > bc)
8334                         padcnt = bc;
8335                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8336                 COUNT_BYTES(padcnt);
8337         }
8338         if(dc){
8339                 CHECK_BYTE_COUNT(dc);
8340                 dissect_nt_trans_data_request(
8341                         tvb, pinfo, offset, tree, dc, &ntd);
8342                 COUNT_BYTES(dc);
8343         }
8344
8345         END_OF_SMB
8346
8347         return offset;
8348 }
8349
8350
8351
8352 static int
8353 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
8354                                int offset, proto_tree *parent_tree, int len,
8355                                nt_trans_data *ntd _U_)
8356 {
8357         proto_item *item = NULL;
8358         proto_tree *tree = NULL;
8359         smb_info_t *si;
8360         smb_nt_transact_info_t *nti;
8361         guint16 bcp;
8362
8363         si = (smb_info_t *)pinfo->private_data;
8364         if (si->sip != NULL)
8365                 nti = si->sip->extra_info;
8366         else
8367                 nti = NULL;
8368
8369         if(parent_tree){
8370                 if(nti != NULL){
8371                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8372                                 "%s Data",
8373                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8374                 } else {
8375                         /*
8376                          * We never saw the request to which this is a
8377                          * response.
8378                          */
8379                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8380                                 "Unknown NT Transaction Data (matching request not seen)");
8381                 }
8382                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8383         }
8384
8385         if (nti == NULL) {
8386                 offset += len;
8387                 return offset;
8388         }
8389         switch(nti->subcmd){
8390         case NT_TRANS_CREATE:
8391                 break;
8392         case NT_TRANS_IOCTL:
8393                 /* ioctl data */
8394                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
8395                 offset += len;
8396
8397                 break;
8398         case NT_TRANS_SSD:
8399                 break;
8400         case NT_TRANS_NOTIFY:
8401                 break;
8402         case NT_TRANS_RENAME:
8403                 /* XXX not documented */
8404                 break;
8405         case NT_TRANS_QSD: {
8406                 /*
8407                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
8408                  * which may be documented in the Win32 documentation
8409                  * somewhere.
8410                  */
8411                 offset = dissect_nt_sec_desc(
8412                         tvb, offset, pinfo, tree, NULL, len, NULL);
8413                 break;
8414         }
8415         case NT_TRANS_GET_USER_QUOTA:
8416                 bcp=len;
8417                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8418                 break;
8419         case NT_TRANS_SET_USER_QUOTA:
8420                 /* not decoded yet */
8421                 break;
8422         }
8423
8424         return offset;
8425 }
8426
8427 static int
8428 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
8429                                 int offset, proto_tree *parent_tree,
8430                                 int len, nt_trans_data *ntd _U_, guint16 bc)
8431 {
8432         proto_item *item = NULL;
8433         proto_tree *tree = NULL;
8434         guint32 fn_len;
8435         const char *fn;
8436         smb_info_t *si;
8437         smb_nt_transact_info_t *nti;
8438         guint16 fid;
8439         int old_offset;
8440         guint32 neo;
8441         int padcnt;
8442
8443         si = (smb_info_t *)pinfo->private_data;
8444         if (si->sip != NULL)
8445                 nti = si->sip->extra_info;
8446         else
8447                 nti = NULL;
8448
8449         if(parent_tree){
8450                 if(nti != NULL){
8451                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8452                                 "%s Parameters",
8453                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8454                 } else {
8455                         /*
8456                          * We never saw the request to which this is a
8457                          * response.
8458                          */
8459                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8460                                 "Unknown NT Transaction Parameters (matching request not seen)");
8461                 }
8462                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8463         }
8464
8465         if (nti == NULL) {
8466                 offset += len;
8467                 return offset;
8468         }
8469         switch(nti->subcmd){
8470         case NT_TRANS_CREATE:
8471                 /* oplock level */
8472                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8473                 offset += 1;
8474
8475                 /* reserved byte */
8476                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8477                 offset += 1;
8478
8479                 /* fid */
8480                 fid = tvb_get_letohs(tvb, offset);
8481                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8482                 offset += 2;
8483
8484                 /* create action */
8485                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8486                 offset += 4;
8487
8488                 /* ea error offset */
8489                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
8490                 offset += 4;
8491
8492                 /* create time */
8493                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8494                         hf_smb_create_time);
8495
8496                 /* access time */
8497                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8498                         hf_smb_access_time);
8499
8500                 /* last write time */
8501                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8502                         hf_smb_last_write_time);
8503
8504                 /* last change time */
8505                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8506                         hf_smb_change_time);
8507
8508                 /* Extended File Attributes */
8509                 offset = dissect_file_ext_attr(tvb, tree, offset);
8510
8511                 /* allocation size */
8512                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8513                 offset += 8;
8514
8515                 /* end of file */
8516                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8517                 offset += 8;
8518
8519                 /* File Type */
8520                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8521                 offset += 2;
8522
8523                 /* device state */
8524                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8525
8526                 /* is directory */
8527                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8528                 offset += 1;
8529                 break;
8530         case NT_TRANS_IOCTL:
8531                 break;
8532         case NT_TRANS_SSD:
8533                 break;
8534         case NT_TRANS_NOTIFY:
8535                 while(len){
8536                         old_offset = offset;
8537
8538                         /* next entry offset */
8539                         neo = tvb_get_letohl(tvb, offset);
8540                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8541                         COUNT_BYTES(4);
8542                         len -= 4;
8543                         /* broken implementations */
8544                         if(len<0)break;
8545
8546                         /* action */
8547                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
8548                         COUNT_BYTES(4);
8549                         len -= 4;
8550                         /* broken implementations */
8551                         if(len<0)break;
8552
8553                         /* file name len */
8554                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
8555                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8556                         COUNT_BYTES(4);
8557                         len -= 4;
8558                         /* broken implementations */
8559                         if(len<0)break;
8560
8561                         /* file name */
8562                         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8563                         if (fn == NULL)
8564                                 break;
8565                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8566                                 fn);
8567                         COUNT_BYTES(fn_len);
8568                         len -= fn_len;
8569                         /* broken implementations */
8570                         if(len<0)break;
8571
8572                         if (neo == 0)
8573                                 break;  /* no more structures */
8574
8575                         /* skip to next structure */
8576                         padcnt = (old_offset + neo) - offset;
8577                         if (padcnt < 0) {
8578                                 /*
8579                                  * XXX - this is bogus; flag it?
8580                                  */
8581                                 padcnt = 0;
8582                         }
8583                         if (padcnt != 0) {
8584                                 COUNT_BYTES(padcnt);
8585                                 len -= padcnt;
8586                                 /* broken implementations */
8587                                 if(len<0)break;
8588                         }
8589                 }
8590                 break;
8591         case NT_TRANS_RENAME:
8592                 /* XXX not documented */
8593                 break;
8594         case NT_TRANS_QSD:
8595                 /*
8596                  * This appears to be the size of the security
8597                  * descriptor; the calling sequence of
8598                  * "ZwQuerySecurityObject()" suggests that it would
8599                  * be.  The actual security descriptor wouldn't
8600                  * follow if the max data count in the request
8601                  * was smaller; this lets the client know how
8602                  * big a buffer it needs to provide.
8603                  */
8604                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
8605                 offset += 4;
8606                 break;
8607         case NT_TRANS_GET_USER_QUOTA:
8608                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
8609                         tvb_get_letohl(tvb, offset));
8610                 offset += 4;
8611                 break;
8612         case NT_TRANS_SET_USER_QUOTA:
8613                 /* not decoded yet */
8614                 break;
8615         }
8616
8617         return offset;
8618 }
8619
8620 static int
8621 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
8622                                 int offset, proto_tree *parent_tree,
8623                                 int len, nt_trans_data *ntd _U_)
8624 {
8625         proto_item *item = NULL;
8626         proto_tree *tree = NULL;
8627         smb_info_t *si;
8628         smb_nt_transact_info_t *nti;
8629
8630         si = (smb_info_t *)pinfo->private_data;
8631         if (si->sip != NULL)
8632                 nti = si->sip->extra_info;
8633         else
8634                 nti = NULL;
8635
8636         if(parent_tree){
8637                 if(nti != NULL){
8638                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8639                                 "%s Setup",
8640                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8641                 } else {
8642                         /*
8643                          * We never saw the request to which this is a
8644                          * response.
8645                          */
8646                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8647                                 "Unknown NT Transaction Setup (matching request not seen)");
8648                 }
8649                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8650         }
8651
8652         if (nti == NULL) {
8653                 offset += len;
8654                 return offset;
8655         }
8656         switch(nti->subcmd){
8657         case NT_TRANS_CREATE:
8658                 break;
8659         case NT_TRANS_IOCTL:
8660                 break;
8661         case NT_TRANS_SSD:
8662                 break;
8663         case NT_TRANS_NOTIFY:
8664                 break;
8665         case NT_TRANS_RENAME:
8666                 /* XXX not documented */
8667                 break;
8668         case NT_TRANS_QSD:
8669                 break;
8670         case NT_TRANS_GET_USER_QUOTA:
8671                 /* not decoded yet */
8672                 break;
8673         case NT_TRANS_SET_USER_QUOTA:
8674                 /* not decoded yet */
8675                 break;
8676         }
8677
8678         return offset;
8679 }
8680
8681 static int
8682 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8683 {
8684         guint8 wc, sc;
8685         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
8686         guint32 td=0, tp=0;
8687         smb_info_t *si;
8688         smb_nt_transact_info_t *nti;
8689         static nt_trans_data ntd;
8690         guint16 bc;
8691         int padcnt;
8692         fragment_data *r_fd = NULL;
8693         tvbuff_t *pd_tvb=NULL;
8694         gboolean save_fragmented;
8695
8696         si = (smb_info_t *)pinfo->private_data;
8697         if (si->sip != NULL)
8698                 nti = si->sip->extra_info;
8699         else
8700                 nti = NULL;
8701
8702         /* primary request */
8703         if(nti != NULL){
8704                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
8705                 if(check_col(pinfo->cinfo, COL_INFO)){
8706                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8707                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
8708                 }
8709         } else {
8710                 proto_tree_add_text(tree, tvb, offset, 0,
8711                         "Function: <unknown function - could not find matching request>");
8712                 if(check_col(pinfo->cinfo, COL_INFO)){
8713                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
8714                 }
8715         }
8716
8717         WORD_COUNT;
8718
8719         /* 3 reserved bytes */
8720         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8721         offset += 3;
8722
8723         /* total param count */
8724         tp = tvb_get_letohl(tvb, offset);
8725         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8726         offset += 4;
8727
8728         /* total data count */
8729         td = tvb_get_letohl(tvb, offset);
8730         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8731         offset += 4;
8732
8733         /* param count */
8734         pc = tvb_get_letohl(tvb, offset);
8735         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8736         offset += 4;
8737
8738         /* param offset */
8739         po = tvb_get_letohl(tvb, offset);
8740         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8741         offset += 4;
8742
8743         /* param displacement */
8744         pd = tvb_get_letohl(tvb, offset);
8745         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8746         offset += 4;
8747
8748         /* data count */
8749         dc = tvb_get_letohl(tvb, offset);
8750         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8751         offset += 4;
8752
8753         /* data offset */
8754         od = tvb_get_letohl(tvb, offset);
8755         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8756         offset += 4;
8757
8758         /* data displacement */
8759         dd = tvb_get_letohl(tvb, offset);
8760         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8761         offset += 4;
8762
8763         /* setup count */
8764         sc = tvb_get_guint8(tvb, offset);
8765         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8766         offset += 1;
8767
8768         /* setup data */
8769         if(sc){
8770                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
8771                 offset += sc*2;
8772         }
8773
8774         BYTE_COUNT;
8775
8776         /* reassembly of SMB NT Transaction data payload.
8777            In this section we do reassembly of both the data and parameters
8778            blocks of the SMB transaction command.
8779         */
8780         save_fragmented = pinfo->fragmented;
8781         /* do we need reassembly? */
8782         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
8783                 /* oh yeah, either data or parameter section needs
8784                    reassembly...
8785                 */
8786                 pinfo->fragmented = TRUE;
8787                 if(smb_trans_reassembly){
8788                         /* ...and we were told to do reassembly */
8789                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
8790                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8791                                                              po, pc, pd, td+tp);
8792
8793                         }
8794                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
8795                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8796                                                              od, dc, dd+tp, td+tp);
8797                         }
8798                 }
8799         }
8800
8801         /* if we got a reassembled fd structure from the reassembly routine we
8802            must create pd_tvb from it
8803         */
8804         if(r_fd){
8805                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
8806                                              r_fd->datalen);
8807                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
8808                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
8809
8810                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
8811         }
8812
8813
8814         if(pd_tvb){
8815           /* we have reassembled data, grab param and data from there */
8816           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
8817                                           &ntd, tvb_length(pd_tvb));
8818           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
8819         } else {
8820           /* we do not have reassembled data, just use what we have in the
8821              packet as well as we can */
8822           /* parameters */
8823           if(po>(guint32)offset){
8824             /* We have some initial padding bytes.
8825              */
8826             padcnt = po-offset;
8827             if (padcnt > bc)
8828               padcnt = bc;
8829             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8830             COUNT_BYTES(padcnt);
8831           }
8832           if(pc){
8833             CHECK_BYTE_COUNT(pc);
8834             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
8835             COUNT_BYTES(pc);
8836           }
8837
8838           /* data */
8839           if(od>(guint32)offset){
8840             /* We have some initial padding bytes.
8841              */
8842             padcnt = od-offset;
8843             if (padcnt > bc)
8844               padcnt = bc;
8845             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8846             COUNT_BYTES(padcnt);
8847           }
8848           if(dc){
8849             CHECK_BYTE_COUNT(dc);
8850             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
8851             COUNT_BYTES(dc);
8852           }
8853         }
8854         pinfo->fragmented = save_fragmented;
8855
8856         END_OF_SMB
8857
8858         return offset;
8859 }
8860
8861 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8862    NT Transaction command  ends here
8863    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8864
8865 static const value_string print_mode_vals[] = {
8866         {0,     "Text Mode"},
8867         {1,     "Graphics Mode"},
8868         {0, NULL}
8869 };
8870
8871 static int
8872 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8873 {
8874         smb_info_t *si = pinfo->private_data;
8875         int fn_len;
8876         const char *fn;
8877         guint8 wc;
8878         guint16 bc;
8879
8880         WORD_COUNT;
8881
8882         /* setup len */
8883         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
8884         offset += 2;
8885
8886         /* print mode */
8887         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
8888         offset += 2;
8889
8890         BYTE_COUNT;
8891
8892         /* buffer format */
8893         CHECK_BYTE_COUNT(1);
8894         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8895         COUNT_BYTES(1);
8896
8897         /* print identifier */
8898         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
8899         if (fn == NULL)
8900                 goto endofcommand;
8901         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
8902                 fn);
8903         COUNT_BYTES(fn_len);
8904
8905         END_OF_SMB
8906
8907         return offset;
8908 }
8909
8910
8911 static int
8912 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8913 {
8914         int cnt;
8915         guint8 wc;
8916         guint16 bc, fid;
8917
8918         WORD_COUNT;
8919
8920         /* fid */
8921         fid = tvb_get_letohs(tvb, offset);
8922         add_fid(tvb, pinfo, tree, offset, 2, fid);
8923         offset += 2;
8924
8925         BYTE_COUNT;
8926
8927         /* buffer format */
8928         CHECK_BYTE_COUNT(1);
8929         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8930         COUNT_BYTES(1);
8931
8932         /* data len */
8933         CHECK_BYTE_COUNT(2);
8934         cnt = tvb_get_letohs(tvb, offset);
8935         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
8936         COUNT_BYTES(2);
8937
8938         /* file data */
8939         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
8940
8941         END_OF_SMB
8942
8943         return offset;
8944 }
8945
8946
8947 static const value_string print_status_vals[] = {
8948         {1,     "Held or Stopped"},
8949         {2,     "Printing"},
8950         {3,     "Awaiting print"},
8951         {4,     "In intercept"},
8952         {5,     "File had error"},
8953         {6,     "Printer error"},
8954         {0, NULL}
8955 };
8956
8957 static int
8958 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8959 {
8960         guint8 wc;
8961         guint16 bc;
8962
8963         WORD_COUNT;
8964
8965         /* max count */
8966         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
8967         offset += 2;
8968
8969         /* start index */
8970         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
8971         offset += 2;
8972
8973         BYTE_COUNT;
8974
8975         END_OF_SMB
8976
8977         return offset;
8978 }
8979
8980 static int
8981 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
8982     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
8983 {
8984         proto_item *item = NULL;
8985         proto_tree *tree = NULL;
8986         smb_info_t *si = pinfo->private_data;
8987         int fn_len;
8988         const char *fn;
8989
8990         if(parent_tree){
8991                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
8992                         "Queue entry");
8993                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
8994         }
8995
8996         /* queued time */
8997         CHECK_BYTE_COUNT_SUBR(4);
8998         offset = dissect_smb_datetime(tvb, tree, offset,
8999                 hf_smb_print_queue_date,
9000                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
9001         *bcp -= 4;
9002
9003         /* status */
9004         CHECK_BYTE_COUNT_SUBR(1);
9005         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
9006         COUNT_BYTES_SUBR(1);
9007
9008         /* spool file number */
9009         CHECK_BYTE_COUNT_SUBR(2);
9010         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
9011         COUNT_BYTES_SUBR(2);
9012
9013         /* spool file size */
9014         CHECK_BYTE_COUNT_SUBR(4);
9015         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
9016         COUNT_BYTES_SUBR(4);
9017
9018         /* reserved byte */
9019         CHECK_BYTE_COUNT_SUBR(1);
9020         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9021         COUNT_BYTES_SUBR(1);
9022
9023         /* file name */
9024         fn_len = 16;
9025         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
9026         CHECK_STRING_SUBR(fn);
9027         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
9028                 fn);
9029         COUNT_BYTES_SUBR(fn_len);
9030
9031         *trunc = FALSE;
9032         return offset;
9033 }
9034
9035 static int
9036 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9037 {
9038         guint16 cnt=0, len;
9039         guint8 wc;
9040         guint16 bc;
9041         gboolean trunc;
9042
9043         WORD_COUNT;
9044
9045         /* count */
9046         cnt = tvb_get_letohs(tvb, offset);
9047         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
9048         offset += 2;
9049
9050         /* restart index */
9051         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
9052         offset += 2;
9053
9054         BYTE_COUNT;
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         /* data len */
9062         CHECK_BYTE_COUNT(2);
9063         len = tvb_get_letohs(tvb, offset);
9064         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
9065         COUNT_BYTES(2);
9066
9067         /* queue elements */
9068         while(cnt--){
9069                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
9070                     &bc, &trunc);
9071                 if (trunc)
9072                         goto endofcommand;
9073         }
9074
9075         END_OF_SMB
9076
9077         return offset;
9078 }
9079
9080
9081 static int
9082 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9083 {
9084         int name_len;
9085         guint16 bc;
9086         guint8 wc;
9087         guint16 message_len;
9088
9089         WORD_COUNT;
9090
9091         BYTE_COUNT;
9092
9093         /* buffer format */
9094         CHECK_BYTE_COUNT(1);
9095         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9096         COUNT_BYTES(1);
9097
9098         /* originator name */
9099         /* XXX - what if this runs past bc? */
9100         name_len = tvb_strsize(tvb, offset);
9101         CHECK_BYTE_COUNT(name_len);
9102         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9103             name_len, TRUE);
9104         COUNT_BYTES(name_len);
9105
9106         /* buffer format */
9107         CHECK_BYTE_COUNT(1);
9108         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9109         COUNT_BYTES(1);
9110
9111         /* destination name */
9112         /* XXX - what if this runs past bc? */
9113         name_len = tvb_strsize(tvb, offset);
9114         CHECK_BYTE_COUNT(name_len);
9115         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9116             name_len, TRUE);
9117         COUNT_BYTES(name_len);
9118
9119         /* buffer format */
9120         CHECK_BYTE_COUNT(1);
9121         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9122         COUNT_BYTES(1);
9123
9124         /* message len */
9125         CHECK_BYTE_COUNT(2);
9126         message_len = tvb_get_letohs(tvb, offset);
9127         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9128             message_len);
9129         COUNT_BYTES(2);
9130
9131         /* message */
9132         CHECK_BYTE_COUNT(message_len);
9133         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9134             TRUE);
9135         COUNT_BYTES(message_len);
9136
9137         END_OF_SMB
9138
9139         return offset;
9140 }
9141
9142 static int
9143 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9144 {
9145         int name_len;
9146         guint16 bc;
9147         guint8 wc;
9148
9149         WORD_COUNT;
9150
9151         BYTE_COUNT;
9152
9153         /* buffer format */
9154         CHECK_BYTE_COUNT(1);
9155         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9156         COUNT_BYTES(1);
9157
9158         /* originator name */
9159         /* XXX - what if this runs past bc? */
9160         name_len = tvb_strsize(tvb, offset);
9161         CHECK_BYTE_COUNT(name_len);
9162         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9163             name_len, TRUE);
9164         COUNT_BYTES(name_len);
9165
9166         /* buffer format */
9167         CHECK_BYTE_COUNT(1);
9168         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9169         COUNT_BYTES(1);
9170
9171         /* destination name */
9172         /* XXX - what if this runs past bc? */
9173         name_len = tvb_strsize(tvb, offset);
9174         CHECK_BYTE_COUNT(name_len);
9175         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9176             name_len, TRUE);
9177         COUNT_BYTES(name_len);
9178
9179         END_OF_SMB
9180
9181         return offset;
9182 }
9183
9184 static int
9185 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9186 {
9187         guint16 bc;
9188         guint8 wc;
9189
9190         WORD_COUNT;
9191
9192         /* message group ID */
9193         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
9194         offset += 2;
9195
9196         BYTE_COUNT;
9197
9198         END_OF_SMB
9199
9200         return offset;
9201 }
9202
9203 static int
9204 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9205 {
9206         guint16 bc;
9207         guint8 wc;
9208         guint16 message_len;
9209
9210         WORD_COUNT;
9211
9212         BYTE_COUNT;
9213
9214         /* buffer format */
9215         CHECK_BYTE_COUNT(1);
9216         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9217         COUNT_BYTES(1);
9218
9219         /* message len */
9220         CHECK_BYTE_COUNT(2);
9221         message_len = tvb_get_letohs(tvb, offset);
9222         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9223             message_len);
9224         COUNT_BYTES(2);
9225
9226         /* message */
9227         CHECK_BYTE_COUNT(message_len);
9228         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9229             TRUE);
9230         COUNT_BYTES(message_len);
9231
9232         END_OF_SMB
9233
9234         return offset;
9235 }
9236
9237 static int
9238 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9239 {
9240         int name_len;
9241         guint16 bc;
9242         guint8 wc;
9243
9244         WORD_COUNT;
9245
9246         BYTE_COUNT;
9247
9248         /* buffer format */
9249         CHECK_BYTE_COUNT(1);
9250         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9251         COUNT_BYTES(1);
9252
9253         /* forwarded name */
9254         /* XXX - what if this runs past bc? */
9255         name_len = tvb_strsize(tvb, offset);
9256         CHECK_BYTE_COUNT(name_len);
9257         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
9258             name_len, TRUE);
9259         COUNT_BYTES(name_len);
9260
9261         END_OF_SMB
9262
9263         return offset;
9264 }
9265
9266 static int
9267 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9268 {
9269         int name_len;
9270         guint16 bc;
9271         guint8 wc;
9272
9273         WORD_COUNT;
9274
9275         BYTE_COUNT;
9276
9277         /* buffer format */
9278         CHECK_BYTE_COUNT(1);
9279         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9280         COUNT_BYTES(1);
9281
9282         /* machine name */
9283         /* XXX - what if this runs past bc? */
9284         name_len = tvb_strsize(tvb, offset);
9285         CHECK_BYTE_COUNT(name_len);
9286         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
9287             name_len, TRUE);
9288         COUNT_BYTES(name_len);
9289
9290         END_OF_SMB
9291
9292         return offset;
9293 }
9294
9295
9296 static int
9297 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9298 {
9299         guint8  wc, cmd=0xff;
9300         guint16 andxoffset=0;
9301         guint16 bc;
9302         smb_info_t *si = pinfo->private_data;
9303         int fn_len;
9304         const char *fn;
9305
9306         WORD_COUNT;
9307
9308         /* next smb command */
9309         cmd = tvb_get_guint8(tvb, offset);
9310         if(cmd!=0xff){
9311                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9312         } else {
9313                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
9314         }
9315         offset += 1;
9316
9317         /* reserved byte */
9318         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9319         offset += 1;
9320
9321         /* andxoffset */
9322         andxoffset = tvb_get_letohs(tvb, offset);
9323         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9324         offset += 2;
9325
9326         /* reserved byte */
9327         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9328         offset += 1;
9329
9330         /* file name len */
9331         fn_len = tvb_get_letohs(tvb, offset);
9332         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
9333         offset += 2;
9334
9335         /* Create flags */
9336         offset = dissect_nt_create_bits(tvb, tree, offset);
9337
9338         /* root directory fid */
9339         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
9340         offset += 4;
9341
9342         /* nt access mask */
9343         offset = dissect_smb_access_mask(tvb, tree, offset);
9344
9345         /* allocation size */
9346         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9347         offset += 8;
9348
9349         /* Extended File Attributes */
9350         offset = dissect_file_ext_attr(tvb, tree, offset);
9351
9352         /* share access */
9353         offset = dissect_nt_share_access(tvb, tree, offset);
9354
9355         /* create disposition */
9356         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
9357         offset += 4;
9358
9359         /* create options */
9360         offset = dissect_nt_create_options(tvb, tree, offset);
9361
9362         /* impersonation level */
9363         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
9364         offset += 4;
9365
9366         /* security flags */
9367         offset = dissect_nt_security_flags(tvb, tree, offset);
9368
9369         BYTE_COUNT;
9370
9371         /* file name */
9372         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9373         if (fn == NULL)
9374                 goto endofcommand;
9375         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9376                 fn);
9377         COUNT_BYTES(fn_len);
9378
9379         if (check_col(pinfo->cinfo, COL_INFO)) {
9380                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
9381         }
9382
9383         END_OF_SMB
9384
9385         /* call AndXCommand (if there are any) */
9386         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9387
9388         return offset;
9389 }
9390
9391
9392 static int
9393 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9394 {
9395         guint8  wc, cmd=0xff;
9396         guint16 andxoffset=0;
9397         guint16 bc;
9398         guint16 fid;
9399
9400         WORD_COUNT;
9401
9402         /* next smb command */
9403         cmd = tvb_get_guint8(tvb, offset);
9404         if(cmd!=0xff){
9405                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9406         } else {
9407                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
9408         }
9409         offset += 1;
9410
9411         /* reserved byte */
9412         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9413         offset += 1;
9414
9415         /* andxoffset */
9416         andxoffset = tvb_get_letohs(tvb, offset);
9417         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9418         offset += 2;
9419
9420         /* oplock level */
9421         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
9422         offset += 1;
9423
9424         /* fid */
9425         fid = tvb_get_letohs(tvb, offset);
9426         add_fid(tvb, pinfo, tree, offset, 2, fid);
9427         offset += 2;
9428
9429         /* create action */
9430         /*XXX is this really the same as create disposition in the request? it looks so*/
9431         /* No, it is not. It is the same as the create action from an Open&X request ... RJS */
9432         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
9433         offset += 4;
9434
9435         /* create time */
9436         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
9437
9438         /* access time */
9439         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
9440
9441         /* last write time */
9442         offset = dissect_smb_64bit_time(tvb, tree, offset,
9443                 hf_smb_last_write_time);
9444
9445         /* last change time */
9446         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
9447
9448         /* Extended File Attributes */
9449         offset = dissect_file_ext_attr(tvb, tree, offset);
9450
9451         /* allocation size */
9452         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9453         offset += 8;
9454
9455         /* end of file */
9456         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9457         offset += 8;
9458
9459         /* File Type */
9460         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
9461         offset += 2;
9462
9463         /* IPC State */
9464         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9465
9466         /* is directory */
9467         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9468         offset += 1;
9469
9470         BYTE_COUNT;
9471
9472         END_OF_SMB
9473
9474         /* call AndXCommand (if there are any) */
9475         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9476
9477         return offset;
9478 }
9479
9480
9481 static int
9482 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9483 {
9484         guint8 wc;
9485         guint16 bc;
9486
9487         WORD_COUNT;
9488
9489         BYTE_COUNT;
9490
9491         END_OF_SMB
9492
9493         return offset;
9494 }
9495
9496 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9497    BEGIN Transaction/Transaction2 Primary and secondary requests
9498    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9499
9500
9501 const value_string trans2_cmd_vals[] = {
9502         { 0x00,         "OPEN2" },
9503         { 0x01,         "FIND_FIRST2" },
9504         { 0x02,         "FIND_NEXT2" },
9505         { 0x03,         "QUERY_FS_INFORMATION" },
9506         { 0x04,         "SET_FS_QUOTA" },
9507         { 0x05,         "QUERY_PATH_INFORMATION" },
9508         { 0x06,         "SET_PATH_INFORMATION" },
9509         { 0x07,         "QUERY_FILE_INFORMATION" },
9510         { 0x08,         "SET_FILE_INFORMATION" },
9511         { 0x09,         "FSCTL" },
9512         { 0x0A,         "IOCTL2" },
9513         { 0x0B,         "FIND_NOTIFY_FIRST" },
9514         { 0x0C,         "FIND_NOTIFY_NEXT" },
9515         { 0x0D,         "CREATE_DIRECTORY" },
9516         { 0x0E,         "SESSION_SETUP" },
9517         { 0x10,         "GET_DFS_REFERRAL" },
9518         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
9519         { 0,    NULL }
9520 };
9521
9522 static const true_false_string tfs_tf_dtid = {
9523         "Also DISCONNECT TID",
9524         "Do NOT disconnect TID"
9525 };
9526 static const true_false_string tfs_tf_owt = {
9527         "One Way Transaction (NO RESPONSE)",
9528         "Two way transaction"
9529 };
9530
9531 static const true_false_string tfs_ff2_backup = {
9532         "Find WITH backup intent",
9533         "No backup intent"
9534 };
9535 static const true_false_string tfs_ff2_continue = {
9536         "CONTINUE search from previous position",
9537         "New search, do NOT continue from previous position"
9538 };
9539 static const true_false_string tfs_ff2_resume = {
9540         "Return RESUME keys",
9541         "Do NOT return resume keys"
9542 };
9543 static const true_false_string tfs_ff2_close_eos = {
9544         "CLOSE search if END OF SEARCH is reached",
9545         "Do NOT close search if end of search reached"
9546 };
9547 static const true_false_string tfs_ff2_close = {
9548         "CLOSE search after this request",
9549         "Do NOT close search after this request"
9550 };
9551
9552 /* used by
9553    TRANS2_FIND_FIRST2
9554 */
9555 static const value_string ff2_il_vals[] = {
9556         { 1,            "Info Standard  (4.3.4.1)"},
9557         { 2,            "Info Query EA Size  (4.3.4.2)"},
9558         { 3,            "Info Query EAs From List  (4.3.4.2)"},
9559         { 0x0101,       "Find File Directory Info  (4.3.4.4)"},
9560         { 0x0102,       "Find File Full Directory Info  (4.3.4.5)"},
9561         { 0x0103,       "Find File Names Info  (4.3.4.7)"},
9562         { 0x0104,       "Find File Both Directory Info  (4.3.4.6)"},
9563         { 0x0202,       "Find File UNIX  (4.3.4.8)"},
9564         {0, NULL}
9565 };
9566
9567 /* values used by :
9568         TRANS2_QUERY_PATH_INFORMATION
9569         TRANS2_QUERY_FILE_INFORMATION
9570 */
9571 static const value_string qpi_loi_vals[] = {
9572         { 1,            "Info Standard  (4.2.16.1)"},
9573         { 2,            "Info Query EA Size  (4.2.16.1)"},
9574         { 3,            "Info Query EAs From List  (4.2.16.2)"},
9575         { 4,            "Info Query All EAs  (4.2.16.2)"},
9576         { 6,            "Info Is Name Valid  (4.2.16.3)"},
9577         { 0x0101,       "Query File Basic Info  (4.2.16.4)"},
9578         { 0x0102,       "Query File Standard Info  (4.2.16.5)"},
9579         { 0x0103,       "Query File EA Info  (4.2.16.6)"},
9580         { 0x0104,       "Query File Name Info  (4.2.16.7)"},
9581         { 0x0107,       "Query File All Info  (4.2.16.8)"},
9582         { 0x0108,       "Query File Alt Name Info  (4.2.16.9)"},
9583         { 0x0109,       "Query File Stream Info  (4.2.16.10)"},
9584         { 0x010b,       "Query File Compression Info  (4.2.16.11)"},
9585         { 0x0200,       "Query File Unix Basic (4.2.16.12)"},
9586         { 0x0201,       "Query File Unix Link (4.2.16.13)"},
9587         { 1004,         "Query File Basic Info  (4.2.16.4)"},
9588         { 1005,         "Query File Standard Info  (4.2.16.5)"},
9589         { 1006,         "Query File Internal Info  (4.2.16.?)"},
9590         { 1007,         "Query File EA Info  (4.2.16.6)"},
9591         { 1009,         "Query File Name Info  (4.2.16.7)"},
9592         { 1010,         "Query File Rename Info  (4.2.16.?)"},
9593         { 1011,         "Query File Link Info  (4.2.16.?)"},
9594         { 1012,         "Query File Names Info  (4.2.16.?)"},
9595         { 1013,         "Query File Disposition Info  (4.2.16.?)"},
9596         { 1014,         "Query File Position Info  (4.2.16.?)"},
9597         { 1015,         "Query File Full EA Info  (4.2.16.?)"},
9598         { 1016,         "Query File Mode Info  (4.2.16.?)"},
9599         { 1017,         "Query File Alignment Info  (4.2.16.?)"},
9600         { 1018,         "Query File All Info  (4.2.16.8)"},
9601         { 1019,         "Query File Allocation Info  (4.2.16.?)"},
9602         { 1020,         "Query File End of File Info  (4.2.16.?)"},
9603         { 1021,         "Query File Alt Name Info  (4.2.16.7)"},
9604         { 1022,         "Query File Stream Info  (4.2.16.10)"},
9605         { 1023,         "Query File Pipe Info  (4.2.16.?)"},
9606         { 1024,         "Query File Pipe Local Info  (4.2.16.?)"},
9607         { 1025,         "Query File Pipe Remote Info  (4.2.16.?)"},
9608         { 1026,         "Query File Mailslot Query Info  (4.2.16.?)"},
9609         { 1027,         "Query File Mailslot Set Info  (4.2.16.?)"},
9610         { 1028,         "Query File Compression Info  (4.2.16.11)"},
9611         { 1029,         "Query File ObjectID Info  (4.2.16.?)"},
9612         { 1030,         "Query File Completion Info  (4.2.16.?)"},
9613         { 1031,         "Query File Move Cluster Info  (4.2.16.?)"},
9614         { 1032,         "Query File Quota Info  (4.2.16.?)"},
9615         { 1033,         "Query File Reparsepoint Info  (4.2.16.?)"},
9616         { 1034,         "Query File Network Open Info  (4.2.16.?)"},
9617         { 1035,         "Query File Attribute Tag Info  (4.2.16.?)"},
9618         { 1036,         "Query File Tracking Info  (4.2.16.?)"},
9619         { 1037,         "Query File Maximum Info  (4.2.16.?)"},
9620         {0, NULL}
9621 };
9622
9623 /* values used by :
9624         TRANS2_SET_PATH_INFORMATION
9625         TRANS2_SET_FILE_INFORMATION
9626         (the SNIA CIFS spec lists some only for TRANS2_SET_FILE_INFORMATION,
9627         but I'm assuming they apply to TRANS2_SET_PATH_INFORMATION as
9628         well; note that they're different from the QUERY_PATH_INFORMATION
9629         and QUERY_FILE_INFORMATION values!)
9630 */
9631 static const value_string spi_loi_vals[] = {
9632         { 1,            "Info Standard  (4.2.18.1)"},
9633         { 2,            "Info Query EA Size  (4.2.18.1)"},
9634         { 4,            "Info Query All EAs  (4.2.18.2)"},
9635         { 0x0101,       "Set File Basic Info  (4.2.19.1)"},
9636         { 0x0102,       "Set File Disposition Info  (4.2.19.2)"},
9637         { 0x0103,       "Set File Allocation Info  (4.2.19.3)"},
9638         { 0x0104,       "Set File End Of File Info  (4.2.19.4)"},
9639         { 0x0200,       "Set File Unix Basic (4.2.18.3)"},
9640         { 0x0201,       "Set File Unix Link (4.2.18.4)"},
9641         { 0x0202,       "Set File Unix HardLink (4.2.18.5)"},
9642         {0, NULL}
9643 };
9644
9645 static const value_string qfsi_vals[] = {
9646         { 1,            "Info Allocation"},
9647         { 2,            "Info Volume"},
9648         { 0x0101,       "Query FS Label Info"},
9649         { 0x0102,       "Query FS Volume Info"},
9650         { 0x0103,       "Query FS Size Info"},
9651         { 0x0104,       "Query FS Device Info"},
9652         { 0x0105,       "Query FS Attribute Info"},
9653         { 0x0301,       "Mac Query FS INFO"},
9654         { 1001,         "Query FS Label Info"},
9655         { 1002,         "Query FS Volume Info"},
9656         { 1003,         "Query FS Size Info"},
9657         { 1004,         "Query FS Device Info"},
9658         { 1005,         "Query FS Attribute Info"},
9659         { 1006,         "Query FS Quota Info"},
9660         { 1007,         "Query Full FS Size Info"},
9661         {0, NULL}
9662 };
9663
9664 static const value_string nt_rename_vals[] = {
9665         { 0x0103,       "Create Hard Link"},
9666         {0, NULL}
9667 };
9668
9669
9670 static const value_string delete_pending_vals[] = {
9671         {0,     "Normal, no pending delete"},
9672         {1,     "This object has DELETE PENDING"},
9673         {0, NULL}
9674 };
9675
9676 static const value_string alignment_vals[] = {
9677         {0,     "Byte alignment"},
9678         {1,     "Word (16bit) alignment"},
9679         {3,     "Long (32bit) alignment"},
9680         {7,     "8 byte boundary alignment"},
9681         {0x0f,  "16 byte boundary alignment"},
9682         {0x1f,  "32 byte boundary alignment"},
9683         {0x3f,  "64 byte boundary alignment"},
9684         {0x7f,  "128 byte boundary alignment"},
9685         {0xff,  "256 byte boundary alignment"},
9686         {0x1ff, "512 byte boundary alignment"},
9687         {0, NULL}
9688 };
9689
9690 static const true_false_string tfs_marked_for_deletion = {
9691         "File is MARKED FOR DELETION",
9692         "File is NOT marked for deletion"
9693 };
9694
9695 static const true_false_string tfs_get_dfs_server_hold_storage = {
9696         "Referral SERVER HOLDS STORAGE for the file",
9697         "Referral server does NOT hold storage for the file"
9698 };
9699 static const true_false_string tfs_get_dfs_fielding = {
9700         "The server in referral is FIELDING CAPABLE",
9701         "The server in referrals is NOT fielding capable"
9702 };
9703
9704 static const true_false_string tfs_dfs_referral_flags_strip = {
9705         "STRIP off pathconsumed characters before submitting",
9706         "Do NOT strip off any characters"
9707 };
9708
9709 static const value_string dfs_referral_server_type_vals[] = {
9710         {0,     "Don't know"},
9711         {1,     "SMB Server"},
9712         {2,     "Netware Server"},
9713         {3,     "Domain Server"},
9714         {0, NULL}
9715 };
9716
9717
9718 static const true_false_string tfs_device_char_removable = {
9719         "This is a REMOVABLE device",
9720         "This is NOT a removable device"
9721 };
9722 static const true_false_string tfs_device_char_read_only = {
9723         "This is a READ-ONLY device",
9724         "This is NOT a read-only device"
9725 };
9726 static const true_false_string tfs_device_char_floppy = {
9727         "This is a FLOPPY DISK device",
9728         "This is NOT a floppy disk device"
9729 };
9730 static const true_false_string tfs_device_char_write_once = {
9731         "This is a WRITE-ONCE device",
9732         "This is NOT a write-once device"
9733 };
9734 static const true_false_string tfs_device_char_remote = {
9735         "This is a REMOTE device",
9736         "This is NOT a remote device"
9737 };
9738 static const true_false_string tfs_device_char_mounted = {
9739         "This device is MOUNTED",
9740         "This device is NOT mounted"
9741 };
9742 static const true_false_string tfs_device_char_virtual = {
9743         "This is a VIRTUAL device",
9744         "This is NOT a virtual device"
9745 };
9746
9747
9748 static const true_false_string tfs_fs_attr_css = {
9749         "This FS supports CASE SENSITIVE SEARCHes",
9750         "This FS does NOT support case sensitive searches"
9751 };
9752 static const true_false_string tfs_fs_attr_cpn = {
9753         "This FS supports CASE PRESERVED NAMES",
9754         "This FS does NOT support case preserved names"
9755 };
9756 static const true_false_string tfs_fs_attr_pacls = {
9757         "This FS supports PERSISTENT ACLs",
9758         "This FS does NOT support persistent acls"
9759 };
9760 static const true_false_string tfs_fs_attr_fc = {
9761         "This FS supports COMPRESSED FILES",
9762         "This FS does NOT support compressed files"
9763 };
9764 static const true_false_string tfs_fs_attr_vq = {
9765         "This FS supports VOLUME QUOTAS",
9766         "This FS does NOT support volume quotas"
9767 };
9768 static const true_false_string tfs_fs_attr_dim = {
9769         "This FS is on a MOUNTED DEVICE",
9770         "This FS is NOT on a mounted device"
9771 };
9772 static const true_false_string tfs_fs_attr_vic = {
9773         "This FS is on a COMPRESSED VOLUME",
9774         "This FS is NOT on a compressed volume"
9775 };
9776
9777 #define FF2_RESUME      0x0004
9778
9779 static int
9780 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9781 {
9782         guint16 mask;
9783         proto_item *item = NULL;
9784         proto_tree *tree = NULL;
9785         smb_info_t *si;
9786         smb_transact2_info_t *t2i;
9787
9788         mask = tvb_get_letohs(tvb, offset);
9789
9790         si = (smb_info_t *)pinfo->private_data;
9791         if (si->sip != NULL) {
9792                 t2i = si->sip->extra_info;
9793                 if (t2i != NULL) {
9794                         if (!pinfo->fd->flags.visited)
9795                                 t2i->resume_keys = (mask & FF2_RESUME);
9796                 }
9797         }
9798
9799         if(parent_tree){
9800                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9801                         "Flags: 0x%04x", mask);
9802                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
9803         }
9804
9805         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
9806                 tvb, offset, 2, mask);
9807         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
9808                 tvb, offset, 2, mask);
9809         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
9810                 tvb, offset, 2, mask);
9811         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
9812                 tvb, offset, 2, mask);
9813         proto_tree_add_boolean(tree, hf_smb_ff2_close,
9814                 tvb, offset, 2, mask);
9815
9816         offset += 2;
9817
9818         return offset;
9819 }
9820
9821 #if 0
9822 static int
9823 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9824 {
9825         guint16 mask;
9826         proto_item *item = NULL;
9827         proto_tree *tree = NULL;
9828
9829         mask = tvb_get_letohs(tvb, offset);
9830
9831         if(parent_tree){
9832                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9833                         "IO Flag: 0x%04x", mask);
9834                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
9835         }
9836
9837         proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
9838                 tvb, offset, 2, mask);
9839         proto_tree_add_boolean(tree, hf_smb_sfi_caching,
9840                 tvb, offset, 2, mask);
9841
9842         offset += 2;
9843
9844         return offset;
9845 }
9846 #endif
9847
9848 static int
9849 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
9850     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
9851 {
9852         proto_item *item = NULL;
9853         proto_tree *tree = NULL;
9854         smb_info_t *si;
9855         smb_transact2_info_t *t2i;
9856         int fn_len;
9857         const char *fn;
9858         int old_offset = offset;
9859
9860         si = (smb_info_t *)pinfo->private_data;
9861         if (si->sip != NULL)
9862                 t2i = si->sip->extra_info;
9863         else
9864                 t2i = NULL;
9865
9866         if(parent_tree){
9867                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
9868                                 "%s Parameters",
9869                                 val_to_str(subcmd, trans2_cmd_vals,
9870                                            "Unknown (0x%02x)"));
9871                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
9872         }
9873
9874         switch(subcmd){
9875         case 0x00:      /*TRANS2_OPEN2*/
9876                 /* open flags */
9877                 CHECK_BYTE_COUNT_TRANS(2);
9878                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
9879                 bc -= 2;
9880
9881                 /* desired access */
9882                 CHECK_BYTE_COUNT_TRANS(2);
9883                 offset = dissect_access(tvb, tree, offset, "Desired");
9884                 bc -= 2;
9885
9886                 /* Search Attributes */
9887                 CHECK_BYTE_COUNT_TRANS(2);
9888                 offset = dissect_search_attributes(tvb, tree, offset);
9889                 bc -= 2;
9890
9891                 /* File Attributes */
9892                 CHECK_BYTE_COUNT_TRANS(2);
9893                 offset = dissect_file_attributes(tvb, tree, offset, 2);
9894                 bc -= 2;
9895
9896                 /* create time */
9897                 CHECK_BYTE_COUNT_TRANS(4);
9898                 offset = dissect_smb_datetime(tvb, tree, offset,
9899                         hf_smb_create_time,
9900                         hf_smb_create_dos_date, hf_smb_create_dos_time,
9901                         TRUE);
9902                 bc -= 4;
9903
9904                 /* open function */
9905                 CHECK_BYTE_COUNT_TRANS(2);
9906                 offset = dissect_open_function(tvb, tree, offset);
9907                 bc -= 2;
9908
9909                 /* allocation size */
9910                 CHECK_BYTE_COUNT_TRANS(4);
9911                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
9912                 COUNT_BYTES_TRANS(4);
9913
9914                 /* 10 reserved bytes */
9915                 CHECK_BYTE_COUNT_TRANS(10);
9916                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
9917                 COUNT_BYTES_TRANS(10);
9918
9919                 /* file name */
9920                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9921                 CHECK_STRING_TRANS(fn);
9922                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9923                         fn);
9924                 COUNT_BYTES_TRANS(fn_len);
9925
9926                 if (check_col(pinfo->cinfo, COL_INFO)) {
9927                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9928                         fn);
9929                 }
9930                 break;
9931         case 0x01:      /*TRANS2_FIND_FIRST2*/
9932                 /* Search Attributes */
9933                 CHECK_BYTE_COUNT_TRANS(2);
9934                 offset = dissect_search_attributes(tvb, tree, offset);
9935                 bc -= 2;
9936
9937                 /* search count */
9938                 CHECK_BYTE_COUNT_TRANS(2);
9939                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
9940                 COUNT_BYTES_TRANS(2);
9941
9942                 /* Find First2 flags */
9943                 CHECK_BYTE_COUNT_TRANS(2);
9944                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
9945                 bc -= 2;
9946
9947                 /* Find First2 information level */
9948                 CHECK_BYTE_COUNT_TRANS(2);
9949                 si->info_level = tvb_get_letohs(tvb, offset);
9950                 if (!pinfo->fd->flags.visited)
9951                         t2i->info_level = si->info_level;
9952                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
9953                 COUNT_BYTES_TRANS(2);
9954
9955                 /* storage type */
9956                 CHECK_BYTE_COUNT_TRANS(4);
9957                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
9958                 COUNT_BYTES_TRANS(4);
9959
9960                 /* search pattern */
9961                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9962                 CHECK_STRING_TRANS(fn);
9963                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
9964                         fn);
9965                 COUNT_BYTES_TRANS(fn_len);
9966
9967                 if (check_col(pinfo->cinfo, COL_INFO)) {
9968                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
9969                         fn);
9970                 }
9971
9972                 break;
9973         case 0x02:      /*TRANS2_FIND_NEXT2*/
9974                 /* sid */
9975                 CHECK_BYTE_COUNT_TRANS(2);
9976                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
9977                 COUNT_BYTES_TRANS(2);
9978
9979                 /* search count */
9980                 CHECK_BYTE_COUNT_TRANS(2);
9981                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
9982                 COUNT_BYTES_TRANS(2);
9983
9984                 /* Find First2 information level */
9985                 CHECK_BYTE_COUNT_TRANS(2);
9986                 si->info_level = tvb_get_letohs(tvb, offset);
9987                 if (!pinfo->fd->flags.visited)
9988                         t2i->info_level = si->info_level;
9989                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
9990                 COUNT_BYTES_TRANS(2);
9991
9992                 /* resume key */
9993                 CHECK_BYTE_COUNT_TRANS(4);
9994                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
9995                 COUNT_BYTES_TRANS(4);
9996
9997                 /* Find First2 flags */
9998                 CHECK_BYTE_COUNT_TRANS(2);
9999                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10000                 bc -= 2;
10001
10002                 /* file name */
10003                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10004                 CHECK_STRING_TRANS(fn);
10005                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10006                         fn);
10007                 COUNT_BYTES_TRANS(fn_len);
10008
10009                 if (check_col(pinfo->cinfo, COL_INFO)) {
10010                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
10011                         fn);
10012                 }
10013
10014                 break;
10015         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10016                 /* level of interest */
10017                 CHECK_BYTE_COUNT_TRANS(2);
10018                 si->info_level = tvb_get_letohs(tvb, offset);
10019                 if (!pinfo->fd->flags.visited)
10020                         t2i->info_level = si->info_level;
10021                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
10022                 COUNT_BYTES_TRANS(2);
10023
10024                 break;
10025         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10026                 /* level of interest */
10027                 CHECK_BYTE_COUNT_TRANS(2);
10028                 si->info_level = tvb_get_letohs(tvb, offset);
10029                 if (!pinfo->fd->flags.visited)
10030                         t2i->info_level = si->info_level;
10031                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10032                 COUNT_BYTES_TRANS(2);
10033
10034                 /* 4 reserved bytes */
10035                 CHECK_BYTE_COUNT_TRANS(4);
10036                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10037                 COUNT_BYTES_TRANS(4);
10038
10039                 /* file name */
10040                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10041                 CHECK_STRING_TRANS(fn);
10042                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10043                         fn);
10044                 COUNT_BYTES_TRANS(fn_len);
10045
10046                 if (check_col(pinfo->cinfo, COL_INFO)) {
10047                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10048                         fn);
10049                 }
10050
10051                 break;
10052         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10053                 /* level of interest */
10054                 CHECK_BYTE_COUNT_TRANS(2);
10055                 si->info_level = tvb_get_letohs(tvb, offset);
10056                 if (!pinfo->fd->flags.visited)
10057                         t2i->info_level = si->info_level;
10058                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10059                 COUNT_BYTES_TRANS(2);
10060
10061                 /* 4 reserved bytes */
10062                 CHECK_BYTE_COUNT_TRANS(4);
10063                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10064                 COUNT_BYTES_TRANS(4);
10065
10066                 /* file name */
10067                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10068                 CHECK_STRING_TRANS(fn);
10069                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10070                         fn);
10071                 COUNT_BYTES_TRANS(fn_len);
10072
10073                 if (check_col(pinfo->cinfo, COL_INFO)) {
10074                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10075                         fn);
10076                 }
10077
10078                 break;
10079         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
10080                 guint16 fid;
10081
10082                 /* fid */
10083                 CHECK_BYTE_COUNT_TRANS(2);
10084                 fid = tvb_get_letohs(tvb, offset);
10085                 add_fid(tvb, pinfo, tree, offset, 2, fid);
10086                 COUNT_BYTES_TRANS(2);
10087
10088                 /* level of interest */
10089                 CHECK_BYTE_COUNT_TRANS(2);
10090                 si->info_level = tvb_get_letohs(tvb, offset);
10091                 if (!pinfo->fd->flags.visited)
10092                         t2i->info_level = si->info_level;
10093                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10094                 COUNT_BYTES_TRANS(2);
10095
10096                 break;
10097         }
10098         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
10099                 guint16 fid;
10100
10101                 /* fid */
10102                 CHECK_BYTE_COUNT_TRANS(2);
10103                 fid = tvb_get_letohs(tvb, offset);
10104                 add_fid(tvb, pinfo, tree, offset, 2, fid);
10105                 COUNT_BYTES_TRANS(2);
10106
10107                 /* level of interest */
10108                 CHECK_BYTE_COUNT_TRANS(2);
10109                 si->info_level = tvb_get_letohs(tvb, offset);
10110                 if (!pinfo->fd->flags.visited)
10111                         t2i->info_level = si->info_level;
10112                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10113                 COUNT_BYTES_TRANS(2);
10114
10115 #if 0
10116                 /*
10117                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10118                  * Extensions Version 3.0, Document Version 1.11,
10119                  * July 19, 1990" says this is I/O flags, but it's
10120                  * reserved in the SNIA spec, and some clients appear
10121                  * to leave junk in it.
10122                  *
10123                  * Is this some field used only if a particular
10124                  * dialect was negotiated, so that clients can feel
10125                  * safe not setting it if they haven't negotiated that
10126                  * dialect?  Or do the (non-OS/2) clients simply not care
10127                  * about that particular OS/2-oriented dialect?
10128                  */
10129
10130                 /* IO Flag */
10131                 CHECK_BYTE_COUNT_TRANS(2);
10132                 offset = dissect_sfi_ioflag(tvb, tree, offset);
10133                 bc -= 2;
10134 #else
10135                 /* 2 reserved bytes */
10136                 CHECK_BYTE_COUNT_TRANS(2);
10137                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10138                 COUNT_BYTES_TRANS(2);
10139 #endif
10140
10141                 break;
10142         }
10143         case 0x09:      /*TRANS2_FSCTL*/
10144                 /* this call has no parameter block in the request */
10145
10146                 /*
10147                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10148                  * Extensions Version 3.0, Document Version 1.11,
10149                  * July 19, 1990" says this this contains a
10150                  * "File system specific parameter block".  (That means
10151                  * we may not be able to dissect it in any case.)
10152                  */
10153                 break;
10154         case 0x0a:      /*TRANS2_IOCTL2*/
10155                 /* this call has no parameter block in the request */
10156
10157                 /*
10158                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10159                  * Extensions Version 3.0, Document Version 1.11,
10160                  * July 19, 1990" says this this contains a
10161                  * "Device/function specific parameter block".  (That
10162                  * means we may not be able to dissect it in any case.)
10163                  */
10164                 break;
10165         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
10166                 /* Search Attributes */
10167                 CHECK_BYTE_COUNT_TRANS(2);
10168                 offset = dissect_search_attributes(tvb, tree, offset);
10169                 bc -= 2;
10170
10171                 /* Number of changes to wait for */
10172                 CHECK_BYTE_COUNT_TRANS(2);
10173                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10174                 COUNT_BYTES_TRANS(2);
10175
10176                 /* Find Notify information level */
10177                 CHECK_BYTE_COUNT_TRANS(2);
10178                 si->info_level = tvb_get_letohs(tvb, offset);
10179                 if (!pinfo->fd->flags.visited)
10180                         t2i->info_level = si->info_level;
10181                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
10182                 COUNT_BYTES_TRANS(2);
10183
10184                 /* 4 reserved bytes */
10185                 CHECK_BYTE_COUNT_TRANS(4);
10186                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10187                 COUNT_BYTES_TRANS(4);
10188
10189                 /* file name */
10190                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10191                 CHECK_STRING_TRANS(fn);
10192                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10193                         fn);
10194                 COUNT_BYTES_TRANS(fn_len);
10195
10196                 if (check_col(pinfo->cinfo, COL_INFO)) {
10197                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10198                         fn);
10199                 }
10200
10201                 break;
10202         }
10203         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
10204                 /* Monitor handle */
10205                 CHECK_BYTE_COUNT_TRANS(2);
10206                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
10207                 COUNT_BYTES_TRANS(2);
10208
10209                 /* Number of changes to wait for */
10210                 CHECK_BYTE_COUNT_TRANS(2);
10211                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10212                 COUNT_BYTES_TRANS(2);
10213
10214                 break;
10215         }
10216         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10217                 /* 4 reserved bytes */
10218                 CHECK_BYTE_COUNT_TRANS(4);
10219                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10220                 COUNT_BYTES_TRANS(4);
10221
10222                 /* dir name */
10223                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
10224                         FALSE, FALSE, &bc);
10225                 CHECK_STRING_TRANS(fn);
10226                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
10227                         fn);
10228                 COUNT_BYTES_TRANS(fn_len);
10229
10230                 if (check_col(pinfo->cinfo, COL_INFO)) {
10231                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
10232                         fn);
10233                 }
10234                 break;
10235         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10236                 /* XXX unknown structure*/
10237                 break;
10238         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10239                 /* referral level */
10240                 CHECK_BYTE_COUNT_TRANS(2);
10241                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
10242                 COUNT_BYTES_TRANS(2);
10243
10244                 /* file name */
10245                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10246                 CHECK_STRING_TRANS(fn);
10247                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10248                         fn);
10249                 COUNT_BYTES_TRANS(fn_len);
10250
10251                 if (check_col(pinfo->cinfo, COL_INFO)) {
10252                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10253                         fn);
10254                 }
10255
10256                 break;
10257         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10258                 /* file name */
10259                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10260                 CHECK_STRING_TRANS(fn);
10261                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10262                         fn);
10263                 COUNT_BYTES_TRANS(fn_len);
10264
10265                 if (check_col(pinfo->cinfo, COL_INFO)) {
10266                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10267                         fn);
10268                 }
10269
10270                 break;
10271         }
10272
10273         /* ooops there were data we didnt know how to process */
10274         if((offset-old_offset) < bc){
10275                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
10276                     bc - (offset-old_offset), TRUE);
10277                 offset += bc - (offset-old_offset);
10278         }
10279
10280         return offset;
10281 }
10282
10283 /*
10284  * XXX - just use "dissect_connect_flags()" here?
10285  */
10286 static guint16
10287 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10288 {
10289         guint16 mask;
10290         proto_item *item = NULL;
10291         proto_tree *tree = NULL;
10292
10293         mask = tvb_get_letohs(tvb, offset);
10294
10295         if(parent_tree){
10296                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10297                         "Flags: 0x%04x", mask);
10298                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
10299         }
10300
10301         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
10302                 tvb, offset, 2, mask);
10303         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
10304                 tvb, offset, 2, mask);
10305
10306         return mask;
10307 }
10308
10309
10310 static int
10311 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10312 {
10313         guint16 mask;
10314         proto_item *item = NULL;
10315         proto_tree *tree = NULL;
10316
10317         mask = tvb_get_letohs(tvb, offset);
10318
10319         if(parent_tree){
10320                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10321                         "Flags: 0x%04x", mask);
10322                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
10323         }
10324
10325         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
10326                 tvb, offset, 2, mask);
10327         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
10328                 tvb, offset, 2, mask);
10329
10330         offset += 2;
10331         return offset;
10332 }
10333
10334 static int
10335 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10336 {
10337         guint16 mask;
10338         proto_item *item = NULL;
10339         proto_tree *tree = NULL;
10340
10341         mask = tvb_get_letohs(tvb, offset);
10342
10343         if(parent_tree){
10344                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10345                         "Flags: 0x%04x", mask);
10346                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
10347         }
10348
10349         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
10350                 tvb, offset, 2, mask);
10351
10352         offset += 2;
10353
10354         return offset;
10355 }
10356
10357
10358 /* dfs inconsistency data  (4.4.2)
10359 */
10360 static int
10361 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
10362     proto_tree *tree, int offset, guint16 *bcp)
10363 {
10364         smb_info_t *si = pinfo->private_data;
10365         int fn_len;
10366         const char *fn;
10367
10368         /*XXX shouldn this data hold version and size? unclear from doc*/
10369         /* referral version */
10370         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10371         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
10372         COUNT_BYTES_TRANS_SUBR(2);
10373
10374         /* referral size */
10375         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10376         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
10377         COUNT_BYTES_TRANS_SUBR(2);
10378
10379         /* referral server type */
10380         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10381         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10382         COUNT_BYTES_TRANS_SUBR(2);
10383
10384         /* referral flags */
10385         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10386         offset = dissect_dfs_referral_flags(tvb, tree, offset);
10387         *bcp -= 2;
10388
10389         /* node name */
10390         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10391         CHECK_STRING_TRANS_SUBR(fn);
10392         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10393                 fn);
10394         COUNT_BYTES_TRANS_SUBR(fn_len);
10395
10396         return offset;
10397 }
10398
10399 /* get dfs referral data  (4.4.1)
10400 */
10401 static int
10402 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
10403     proto_tree *tree, int offset, guint16 *bcp)
10404 {
10405         smb_info_t *si = pinfo->private_data;
10406         guint16 numref;
10407         guint16 refsize;
10408         guint16 pathoffset;
10409         guint16 altpathoffset;
10410         guint16 nodeoffset;
10411         int fn_len;
10412         int stroffset;
10413         int offsetoffset;
10414         guint16 save_bc;
10415         const char *fn;
10416         int unklen;
10417         int ucstring_end;
10418         int ucstring_len;
10419
10420         /* path consumed */
10421         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10422         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
10423         COUNT_BYTES_TRANS_SUBR(2);
10424
10425         /* num referrals */
10426         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10427         numref = tvb_get_letohs(tvb, offset);
10428         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
10429         COUNT_BYTES_TRANS_SUBR(2);
10430
10431         /* get dfs flags */
10432         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10433         offset = dissect_get_dfs_flags(tvb, tree, offset);
10434         *bcp -= 2;
10435
10436         /* XXX - in at least one capture there appears to be 2 bytes
10437            of stuff after the Dfs flags, perhaps so that the header
10438            in front of the referral list is a multiple of 4 bytes long. */
10439         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10440         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
10441         COUNT_BYTES_TRANS_SUBR(2);
10442
10443         /* if there are any referrals */
10444         if(numref){
10445                 proto_item *ref_item = NULL;
10446                 proto_tree *ref_tree = NULL;
10447                 int old_offset=offset;
10448
10449                 if(tree){
10450                         ref_item = proto_tree_add_text(tree,
10451                                 tvb, offset, *bcp, "Referrals");
10452                         ref_tree = proto_item_add_subtree(ref_item,
10453                                 ett_smb_dfs_referrals);
10454                 }
10455                 ucstring_end = -1;
10456
10457                 while(numref--){
10458                         proto_item *ri = NULL;
10459                         proto_tree *rt = NULL;
10460                         int old_offset=offset;
10461                         guint16 version;
10462
10463                         if(tree){
10464                                 ri = proto_tree_add_text(ref_tree,
10465                                         tvb, offset, *bcp, "Referral");
10466                                 rt = proto_item_add_subtree(ri,
10467                                         ett_smb_dfs_referral);
10468                         }
10469
10470                         /* referral version */
10471                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10472                         version = tvb_get_letohs(tvb, offset);
10473                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
10474                                 tvb, offset, 2, version);
10475                         COUNT_BYTES_TRANS_SUBR(2);
10476
10477                         /* referral size */
10478                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10479                         refsize = tvb_get_letohs(tvb, offset);
10480                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
10481                         COUNT_BYTES_TRANS_SUBR(2);
10482
10483                         /* referral server type */
10484                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10485                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10486                         COUNT_BYTES_TRANS_SUBR(2);
10487
10488                         /* referral flags */
10489                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10490                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
10491                         *bcp -= 2;
10492
10493                         switch(version){
10494
10495                         case 1:
10496                                 /* node name */
10497                                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10498                                 CHECK_STRING_TRANS_SUBR(fn);
10499                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10500                                         fn);
10501                                 COUNT_BYTES_TRANS_SUBR(fn_len);
10502                                 break;
10503
10504                         case 2:
10505                         case 3: /* XXX - like version 2, but not identical;
10506                                    seen in a capture, but the format isn't
10507                                    documented */
10508                                 /* proximity */
10509                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10510                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
10511                                 COUNT_BYTES_TRANS_SUBR(2);
10512
10513                                 /* ttl */
10514                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10515                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
10516                                 COUNT_BYTES_TRANS_SUBR(2);
10517
10518                                 /* path offset */
10519                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10520                                 pathoffset = tvb_get_letohs(tvb, offset);
10521                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
10522                                 COUNT_BYTES_TRANS_SUBR(2);
10523
10524                                 /* alt path offset */
10525                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10526                                 altpathoffset = tvb_get_letohs(tvb, offset);
10527                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
10528                                 COUNT_BYTES_TRANS_SUBR(2);
10529
10530                                 /* node offset */
10531                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10532                                 nodeoffset = tvb_get_letohs(tvb, offset);
10533                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
10534                                 COUNT_BYTES_TRANS_SUBR(2);
10535
10536                                 /* path */
10537                                 if (pathoffset != 0) {
10538                                         stroffset = old_offset + pathoffset;
10539                                         offsetoffset = stroffset - offset;
10540                                         if (offsetoffset > 0 &&
10541                                             *bcp > offsetoffset) {
10542                                                 save_bc = *bcp;
10543                                                 *bcp -= offsetoffset;
10544                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10545                                                 CHECK_STRING_TRANS_SUBR(fn);
10546                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
10547                                                         fn);
10548                                                 stroffset += fn_len;
10549                                                 if (ucstring_end < stroffset)
10550                                                         ucstring_end = stroffset;
10551                                                 *bcp = save_bc;
10552                                         }
10553                                 }
10554
10555                                 /* alt path */
10556                                 if (altpathoffset != 0) {
10557                                         stroffset = old_offset + altpathoffset;
10558                                         offsetoffset = stroffset - offset;
10559                                         if (offsetoffset > 0 &&
10560                                             *bcp > offsetoffset) {
10561                                                 save_bc = *bcp;
10562                                                 *bcp -= offsetoffset;
10563                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10564                                                 CHECK_STRING_TRANS_SUBR(fn);
10565                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
10566                                                         fn);
10567                                                 stroffset += fn_len;
10568                                                 if (ucstring_end < stroffset)
10569                                                         ucstring_end = stroffset;
10570                                                 *bcp = save_bc;
10571                                         }
10572                                 }
10573
10574                                 /* node */
10575                                 if (nodeoffset != 0) {
10576                                         stroffset = old_offset + nodeoffset;
10577                                         offsetoffset = stroffset - offset;
10578                                         if (offsetoffset > 0 &&
10579                                             *bcp > offsetoffset) {
10580                                                 save_bc = *bcp;
10581                                                 *bcp -= offsetoffset;
10582                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10583                                                 CHECK_STRING_TRANS_SUBR(fn);
10584                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
10585                                                         fn);
10586                                                 stroffset += fn_len;
10587                                                 if (ucstring_end < stroffset)
10588                                                         ucstring_end = stroffset;
10589                                                 *bcp = save_bc;
10590                                         }
10591                                 }
10592                                 break;
10593                         }
10594
10595                         /*
10596                          * Show anything beyond the length of the referral
10597                          * as unknown data.
10598                          */
10599                         unklen = (old_offset + refsize) - offset;
10600                         if (unklen < 0) {
10601                                 /*
10602                                  * XXX - the length is bogus.
10603                                  */
10604                                 unklen = 0;
10605                         }
10606                         if (unklen != 0) {
10607                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
10608                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
10609                                     offset, unklen, TRUE);
10610                                 COUNT_BYTES_TRANS_SUBR(unklen);
10611                         }
10612
10613                         proto_item_set_len(ri, offset-old_offset);
10614                 }
10615
10616                 /*
10617                  * Treat the offset past the end of the last Unicode
10618                  * string after the referrals (if any) as the last
10619                  * offset.
10620                  */
10621                 if (ucstring_end > offset) {
10622                         ucstring_len = ucstring_end - offset;
10623                         if (*bcp < ucstring_len)
10624                                 ucstring_len = *bcp;
10625                         offset += ucstring_len;
10626                         *bcp -= ucstring_len;
10627                 }
10628                 proto_item_set_len(ref_item, offset-old_offset);
10629         }
10630
10631         return offset;
10632 }
10633
10634
10635 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
10636    as described in 4.2.16.1
10637 */
10638 static int
10639 dissect_4_2_16_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10640     int offset, guint16 *bcp, gboolean *trunc)
10641 {
10642         /* create time */
10643         CHECK_BYTE_COUNT_SUBR(4);
10644         offset = dissect_smb_datetime(tvb, tree, offset,
10645                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
10646                 FALSE);
10647         *bcp -= 4;
10648
10649         /* access time */
10650         CHECK_BYTE_COUNT_SUBR(4);
10651         offset = dissect_smb_datetime(tvb, tree, offset,
10652                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
10653                 FALSE);
10654         *bcp -= 4;
10655
10656         /* last write time */
10657         CHECK_BYTE_COUNT_SUBR(4);
10658         offset = dissect_smb_datetime(tvb, tree, offset,
10659                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
10660                 FALSE);
10661         *bcp -= 4;
10662
10663         /* data size */
10664         CHECK_BYTE_COUNT_SUBR(4);
10665         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10666         COUNT_BYTES_SUBR(4);
10667
10668         /* allocation size */
10669         CHECK_BYTE_COUNT_SUBR(4);
10670         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10671         COUNT_BYTES_SUBR(4);
10672
10673         /* File Attributes */
10674         CHECK_BYTE_COUNT_SUBR(2);
10675         offset = dissect_file_attributes(tvb, tree, offset, 2);
10676         *bcp -= 2;
10677
10678         /* ea length */
10679         CHECK_BYTE_COUNT_SUBR(4);
10680         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10681         COUNT_BYTES_SUBR(4);
10682
10683         *trunc = FALSE;
10684         return offset;
10685 }
10686
10687 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
10688    as described in 4.2.16.2
10689 */
10690 static int
10691 dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10692     int offset, guint16 *bcp, gboolean *trunc)
10693 {
10694         guint8 name_len;
10695         guint16 data_len;
10696         /* EA size */
10697
10698         CHECK_BYTE_COUNT_SUBR(4);
10699         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10700         COUNT_BYTES_SUBR(4);
10701
10702         while (*bcp > 0) {
10703                 proto_item *item;
10704                 proto_tree *subtree;
10705                 int start_offset = offset;
10706                 guint8 *name;
10707
10708                 item = proto_tree_add_text(
10709                         tree, tvb, offset, 0, "Extended Attribute");
10710                 subtree = proto_item_add_subtree(item, ett_smb_ea);
10711
10712                 /* EA flags */
10713                 
10714                 CHECK_BYTE_COUNT_SUBR(1);
10715                 proto_tree_add_item(
10716                         subtree, hf_smb_ea_flags, tvb, offset, 1, TRUE);
10717                 COUNT_BYTES_SUBR(1);
10718
10719                 /* EA name length */
10720                 
10721                 name_len = tvb_get_guint8(tvb, offset);
10722
10723                 CHECK_BYTE_COUNT_SUBR(1);
10724                 proto_tree_add_item(
10725                         subtree, hf_smb_ea_name_length, tvb, offset, 1, TRUE);
10726                 COUNT_BYTES_SUBR(1);
10727
10728                 /* EA data length */
10729
10730                 data_len = tvb_get_letohs(tvb, offset);
10731                 
10732                 CHECK_BYTE_COUNT_SUBR(2);
10733                 proto_tree_add_item(
10734                         subtree, hf_smb_ea_data_length, tvb, offset, 2, TRUE);
10735                 COUNT_BYTES_SUBR(2);
10736
10737                 /* EA name */
10738
10739                 name = tvb_get_string(tvb, offset, name_len);
10740                 proto_item_append_text(item, ": %s", name);
10741                 g_free(name);
10742
10743                 CHECK_BYTE_COUNT_SUBR(name_len + 1);
10744                 proto_tree_add_item(
10745                         subtree, hf_smb_ea_name, tvb, offset, name_len + 1, 
10746                         TRUE);
10747                 COUNT_BYTES_SUBR(name_len + 1);
10748
10749                 /* EA data */
10750                 
10751                 CHECK_BYTE_COUNT_SUBR(data_len);
10752                 proto_tree_add_item(
10753                         subtree, hf_smb_ea_data, tvb, offset, data_len, TRUE);
10754                 COUNT_BYTES_SUBR(data_len);
10755
10756                 proto_item_set_len(item, offset - start_offset);
10757         }
10758
10759         *trunc = FALSE;
10760         return offset;
10761 }
10762
10763 /* this dissects the SMB_INFO_IS_NAME_VALID
10764    as described in 4.2.16.3
10765 */
10766 static int
10767 dissect_4_2_16_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10768     int offset, guint16 *bcp, gboolean *trunc)
10769 {
10770         smb_info_t *si = pinfo->private_data;
10771         int fn_len;
10772         const char *fn;
10773
10774         /* file name */
10775         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10776         CHECK_STRING_SUBR(fn);
10777         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10778                 fn);
10779         COUNT_BYTES_SUBR(fn_len);
10780
10781         *trunc = FALSE;
10782         return offset;
10783 }
10784
10785 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
10786    as described in 4.2.16.4
10787 */
10788 static int
10789 dissect_4_2_16_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10790     int offset, guint16 *bcp, gboolean *trunc)
10791 {
10792         /* create time */
10793         CHECK_BYTE_COUNT_SUBR(8);
10794         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
10795         *bcp -= 8;
10796
10797         /* access time */
10798         CHECK_BYTE_COUNT_SUBR(8);
10799         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
10800         *bcp -= 8;
10801
10802         /* last write time */
10803         CHECK_BYTE_COUNT_SUBR(8);
10804         offset = dissect_smb_64bit_time(tvb, tree, offset,
10805                 hf_smb_last_write_time);
10806         *bcp -= 8;
10807
10808         /* last change time */
10809         CHECK_BYTE_COUNT_SUBR(8);
10810         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
10811         *bcp -= 8;
10812
10813         /* File Attributes */
10814         CHECK_BYTE_COUNT_SUBR(4);
10815         offset = dissect_file_attributes(tvb, tree, offset, 4);
10816         *bcp -= 4;
10817
10818         *trunc = FALSE;
10819         return offset;
10820 }
10821
10822 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
10823    as described in 4.2.16.5
10824 */
10825 static int
10826 dissect_4_2_16_5(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10827     int offset, guint16 *bcp, gboolean *trunc)
10828 {
10829         /* allocation size */
10830         CHECK_BYTE_COUNT_SUBR(8);
10831         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10832         COUNT_BYTES_SUBR(8);
10833
10834         /* end of file */
10835         CHECK_BYTE_COUNT_SUBR(8);
10836         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10837         COUNT_BYTES_SUBR(8);
10838
10839         /* number of links */
10840         CHECK_BYTE_COUNT_SUBR(4);
10841         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
10842         COUNT_BYTES_SUBR(4);
10843
10844         /* delete pending */
10845         CHECK_BYTE_COUNT_SUBR(1);
10846         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
10847         COUNT_BYTES_SUBR(1);
10848
10849         /* is directory */
10850         CHECK_BYTE_COUNT_SUBR(1);
10851         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
10852         COUNT_BYTES_SUBR(1);
10853
10854         *trunc = FALSE;
10855         return offset;
10856 }
10857
10858 /* this dissects the SMB_QUERY_FILE_EA_INFO
10859    as described in 4.2.16.6
10860 */
10861 static int
10862 dissect_4_2_16_6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10863     int offset, guint16 *bcp, gboolean *trunc)
10864 {
10865         /* ea length */
10866         CHECK_BYTE_COUNT_SUBR(4);
10867         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10868         COUNT_BYTES_SUBR(4);
10869
10870         *trunc = FALSE;
10871         return offset;
10872 }
10873
10874 /* this dissects the SMB_QUERY_FILE_NAME_INFO
10875    as described in 4.2.16.7
10876    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
10877    as described in 4.2.16.9
10878 */
10879 static int
10880 dissect_4_2_16_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10881     int offset, guint16 *bcp, gboolean *trunc)
10882 {
10883         smb_info_t *si = pinfo->private_data;
10884         int fn_len;
10885         const char *fn;
10886
10887         /* file name len */
10888         CHECK_BYTE_COUNT_SUBR(4);
10889         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
10890         COUNT_BYTES_SUBR(4);
10891
10892         /* file name */
10893         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10894         CHECK_STRING_SUBR(fn);
10895         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10896                 fn);
10897         COUNT_BYTES_SUBR(fn_len);
10898
10899         *trunc = FALSE;
10900         return offset;
10901 }
10902
10903 /* this dissects the SMB_QUERY_FILE_ALL_INFO
10904    as described in 4.2.16.8
10905 */
10906 static int
10907 dissect_4_2_16_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10908     int offset, guint16 *bcp, gboolean *trunc)
10909 {
10910
10911         offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp, trunc);
10912         if (*trunc) {
10913                 return offset;
10914         }
10915         offset = dissect_4_2_16_5(tvb, pinfo, tree, offset, bcp, trunc);
10916         if (*trunc) {
10917                 return offset;
10918         }
10919
10920         /* index number */
10921         CHECK_BYTE_COUNT_SUBR(8);
10922         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
10923         COUNT_BYTES_SUBR(8);
10924
10925         offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp, trunc);
10926         if (*trunc)
10927                 return offset;
10928
10929         /* access flags */
10930         CHECK_BYTE_COUNT_SUBR(4);
10931         offset = dissect_smb_access_mask(tvb, tree, offset);
10932         COUNT_BYTES_SUBR(4);
10933
10934         /* index number */
10935         CHECK_BYTE_COUNT_SUBR(8);
10936         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
10937         COUNT_BYTES_SUBR(8);
10938
10939         /* current offset */
10940         CHECK_BYTE_COUNT_SUBR(8);
10941         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
10942         COUNT_BYTES_SUBR(8);
10943
10944         /* mode */
10945         CHECK_BYTE_COUNT_SUBR(4);
10946         offset = dissect_nt_create_options(tvb, tree, offset);
10947         *bcp -= 4;
10948
10949         /* alignment */
10950         CHECK_BYTE_COUNT_SUBR(4);
10951         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
10952         COUNT_BYTES_SUBR(4);
10953
10954         offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp, trunc);
10955
10956         return offset;
10957 }
10958
10959 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
10960    as described in 4.2.16.10
10961 */
10962 static int
10963 dissect_4_2_16_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10964     int offset, guint16 *bcp, gboolean *trunc)
10965 {
10966         proto_item *item;
10967         proto_tree *tree;
10968         int old_offset;
10969         guint32 neo;
10970         smb_info_t *si = pinfo->private_data;
10971         int fn_len;
10972         const char *fn;
10973         int padcnt;
10974
10975         for (;;) {
10976                 old_offset = offset;
10977
10978                 /* next entry offset */
10979                 CHECK_BYTE_COUNT_SUBR(4);
10980                 if(parent_tree){
10981                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
10982                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10983                 } else {
10984                         item = NULL;
10985                         tree = NULL;
10986                 }
10987
10988                 neo = tvb_get_letohl(tvb, offset);
10989                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10990                 COUNT_BYTES_SUBR(4);
10991
10992                 /* stream name len */
10993                 CHECK_BYTE_COUNT_SUBR(4);
10994                 fn_len = tvb_get_letohl(tvb, offset);
10995                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
10996                 COUNT_BYTES_SUBR(4);
10997
10998                 /* stream size */
10999                 CHECK_BYTE_COUNT_SUBR(8);
11000                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
11001                 COUNT_BYTES_SUBR(8);
11002
11003                 /* allocation size */
11004                 CHECK_BYTE_COUNT_SUBR(8);
11005                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11006                 COUNT_BYTES_SUBR(8);
11007
11008                 /* stream name */
11009                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11010                 CHECK_STRING_SUBR(fn);
11011                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
11012                         fn);
11013                 COUNT_BYTES_SUBR(fn_len);
11014
11015                 proto_item_append_text(item, ": %s", fn);
11016                 proto_item_set_len(item, offset-old_offset);
11017
11018                 if (neo == 0)
11019                         break;  /* no more structures */
11020
11021                 /* skip to next structure */
11022                 padcnt = (old_offset + neo) - offset;
11023                 if (padcnt < 0) {
11024                         /*
11025                          * XXX - this is bogus; flag it?
11026                          */
11027                         padcnt = 0;
11028                 }
11029                 if (padcnt != 0) {
11030                         CHECK_BYTE_COUNT_SUBR(padcnt);
11031                         COUNT_BYTES_SUBR(padcnt);
11032                 }
11033         }
11034
11035         *trunc = FALSE;
11036         return offset;
11037 }
11038
11039 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
11040    as described in 4.2.16.11
11041 */
11042 static int
11043 dissect_4_2_16_11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11044     int offset, guint16 *bcp, gboolean *trunc)
11045 {
11046         /* compressed file size */
11047         CHECK_BYTE_COUNT_SUBR(8);
11048         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
11049         COUNT_BYTES_SUBR(8);
11050
11051         /* compression format */
11052         CHECK_BYTE_COUNT_SUBR(2);
11053         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
11054         COUNT_BYTES_SUBR(2);
11055
11056         /* compression unit shift */
11057         CHECK_BYTE_COUNT_SUBR(1);
11058         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
11059         COUNT_BYTES_SUBR(1);
11060
11061         /* compression chunk shift */
11062         CHECK_BYTE_COUNT_SUBR(1);
11063         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
11064         COUNT_BYTES_SUBR(1);
11065
11066         /* compression cluster shift */
11067         CHECK_BYTE_COUNT_SUBR(1);
11068         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
11069         COUNT_BYTES_SUBR(1);
11070
11071         /* 3 reserved bytes */
11072         CHECK_BYTE_COUNT_SUBR(3);
11073         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
11074         COUNT_BYTES_SUBR(3);
11075
11076         *trunc = FALSE;
11077         return offset;
11078 }
11079
11080 /* this dissects the SMB_SET_FILE_DISPOSITION_INFO
11081    as described in 4.2.19.2
11082 */
11083 static int
11084 dissect_4_2_19_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11085     int offset, guint16 *bcp, gboolean *trunc)
11086 {
11087         /* marked for deletion? */
11088         CHECK_BYTE_COUNT_SUBR(1);
11089         proto_tree_add_item(tree, hf_smb_t2_marked_for_deletion, tvb, offset, 1, TRUE);
11090         COUNT_BYTES_SUBR(1);
11091
11092         *trunc = FALSE;
11093         return offset;
11094 }
11095
11096 /* this dissects the SMB_SET_FILE_ALLOCATION_INFO
11097    as described in 4.2.19.3
11098 */
11099 static int
11100 dissect_4_2_19_3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11101     int offset, guint16 *bcp, gboolean *trunc)
11102 {
11103         /* file allocation size */
11104         CHECK_BYTE_COUNT_SUBR(8);
11105         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11106         COUNT_BYTES_SUBR(8);
11107
11108         *trunc = FALSE;
11109         return offset;
11110 }
11111
11112 /* this dissects the SMB_SET_FILE_END_OF_FILE_INFO
11113    as described in 4.2.19.4
11114 */
11115 static int
11116 dissect_4_2_19_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11117     int offset, guint16 *bcp, gboolean *trunc)
11118 {
11119         /* file end of file offset */
11120         CHECK_BYTE_COUNT_SUBR(8);
11121         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11122         COUNT_BYTES_SUBR(8);
11123
11124         *trunc = FALSE;
11125         return offset;
11126 }
11127
11128
11129
11130
11131 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION and
11132   TRANS2_QUERY_FILE_INFORMATION*/
11133 static int
11134 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11135     int offset, guint16 *bcp)
11136 {
11137         smb_info_t *si;
11138         gboolean trunc;
11139
11140         if(!*bcp){
11141                 return offset;
11142         }
11143
11144         si = (smb_info_t *)pinfo->private_data;
11145         switch(si->info_level){
11146         case 1:         /*Info Standard*/
11147                 
11148         case 2:         /*Info Query EA Size*/
11149                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
11150                     &trunc);
11151                 break;
11152         case 3:         /*Info Query EAs From List*/
11153         case 4:         /*Info Query All EAs*/
11154                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11155                     &trunc);
11156                 break;
11157         case 6:         /*Info Is Name Valid*/
11158                 offset = dissect_4_2_16_3(tvb, pinfo, tree, offset, bcp,
11159                     &trunc);
11160                 break;
11161         case 0x0101:    /*Query File Basic Info*/
11162         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
11163                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11164                     &trunc);
11165                 break;
11166         case 0x0102:    /*Query File Standard Info*/
11167         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
11168                 offset = dissect_4_2_16_5(tvb, pinfo, tree, offset, bcp,
11169                     &trunc);
11170                 break;
11171         case 0x0103:    /*Query File EA Info*/
11172         case 1007:      /* SMB_FILE_EA_INFORMATION */
11173                 offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp,
11174                     &trunc);
11175                 break;
11176         case 0x0104:    /*Query File Name Info*/
11177         case 1009:      /* SMB_FILE_NAME_INFORMATION */
11178                 offset = dissect_4_2_16_7(tvb, pinfo, tree, offset, bcp,
11179                     &trunc);
11180                 break;
11181         case 0x0107:    /*Query File All Info*/
11182         case 1018:      /* SMB_FILE_ALL_INFORMATION */
11183                 offset = dissect_4_2_16_8(tvb, pinfo, tree, offset, bcp,
11184                     &trunc);
11185                 break;
11186         case 0x0108:    /*Query File Alt File Info*/
11187         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
11188                 offset = dissect_4_2_16_7(tvb, pinfo, tree, offset, bcp,
11189                     &trunc);
11190                 break;
11191         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
11192                 ((smb_info_t *)(pinfo->private_data))->unicode = TRUE;
11193         case 0x0109:    /*Query File Stream Info*/
11194                 offset = dissect_4_2_16_10(tvb, pinfo, tree, offset, bcp,
11195                     &trunc);
11196                 break;
11197         case 0x010b:    /*Query File Compression Info*/
11198         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
11199                 offset = dissect_4_2_16_11(tvb, pinfo, tree, offset, bcp,
11200                     &trunc);
11201                 break;
11202         case 0x0200:    /*Set File Unix Basic*/
11203                 /* XXX add this from the SNIA doc */
11204                 break;
11205         case 0x0201:    /*Set File Unix Link*/
11206                 /* XXX add this from the SNIA doc */
11207                 break;
11208         case 0x0202:    /*Set File Unix HardLink*/
11209                 /* XXX add this from the SNIA doc */
11210                 break;
11211         }
11212
11213         return offset;
11214 }
11215
11216 /*dissect the data block for TRANS2_SET_PATH_INFORMATION and
11217   TRANS2_SET_FILE_INFORMATION*/
11218 static int
11219 dissect_spi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11220     int offset, guint16 *bcp)
11221 {
11222         smb_info_t *si;
11223         gboolean trunc;
11224
11225         if(!*bcp){
11226                 return offset;
11227         }
11228
11229         si = (smb_info_t *)pinfo->private_data;
11230         switch(si->info_level){
11231         case 1:         /*Info Standard*/
11232                 
11233         case 2:         /*Info Query EA Size*/
11234                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
11235                     &trunc);
11236                 break;
11237         case 4:         /*Info Query All EAs*/
11238                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11239                     &trunc);
11240                 break;
11241         case 0x0101:    /*Set File Basic Info*/
11242                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11243                     &trunc);
11244                 break;
11245         case 0x0102:    /*Set File Disposition Info*/
11246                 offset = dissect_4_2_19_2(tvb, pinfo, tree, offset, bcp,
11247                     &trunc);
11248                 break;
11249         case 0x0103:    /*Set File Allocation Info*/
11250                 offset = dissect_4_2_19_3(tvb, pinfo, tree, offset, bcp,
11251                     &trunc);
11252                 break;
11253         case 0x0104:    /*Set End Of File Info*/
11254                 offset = dissect_4_2_19_4(tvb, pinfo, tree, offset, bcp,
11255                     &trunc);
11256                 break;
11257         case 0x0200:    /*Set File Unix Basic*/
11258                 /* XXX add this from the SNIA doc */
11259                 break;
11260         case 0x0201:    /*Set File Unix Link*/
11261                 /* XXX add this from the SNIA doc */
11262                 break;
11263         case 0x0203:    /*Set File Unix HardLink*/
11264                 /* XXX add this from the SNIA doc */
11265                 break;
11266         }
11267
11268         return offset;
11269 }
11270
11271
11272 static const true_false_string tfs_quota_flags_deny_disk = {
11273         "DENY DISK SPACE for users exceeding quota limit",
11274         "Do NOT deny disk space for users exceeding quota limit"
11275 };
11276 static const true_false_string tfs_quota_flags_log_limit = {
11277         "LOG EVENT when a user exceeds their QUOTA LIMIT",
11278         "Do NOT log event when a user exceeds their quota limit"
11279 };
11280 static const true_false_string tfs_quota_flags_log_warning = {
11281         "LOG EVENT when a user exceeds their WARNING LEVEL",
11282         "Do NOT log event when a user exceeds their warning level"
11283 };
11284 static const true_false_string tfs_quota_flags_enabled = {
11285         "Quotas are ENABLED of this fs",
11286         "Quotas are NOT enabled on this fs"
11287 };
11288 static void
11289 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11290 {
11291         guint8 mask;
11292         proto_item *item = NULL;
11293         proto_tree *tree = NULL;
11294
11295         mask = tvb_get_guint8(tvb, offset);
11296
11297         if(parent_tree){
11298                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
11299                         "Quota Flags: 0x%02x %s", mask,
11300                         mask?"Enabled":"Disabled");
11301                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
11302         }
11303
11304         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
11305                 tvb, offset, 1, mask);
11306         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
11307                 tvb, offset, 1, mask);
11308         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
11309                 tvb, offset, 1, mask);
11310
11311         if(mask && (!(mask&0x01))){
11312                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
11313                         tvb, offset, 1, 0x01);
11314         } else {
11315                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
11316                         tvb, offset, 1, mask);
11317         }
11318
11319 }
11320
11321 static int
11322 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
11323 {
11324         /* first 24 bytes are unknown */
11325         CHECK_BYTE_COUNT_TRANS_SUBR(24);
11326         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11327                     offset, 24, TRUE);
11328         COUNT_BYTES_TRANS_SUBR(24);
11329
11330         /* number of bytes for quota warning */
11331         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11332         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
11333         COUNT_BYTES_TRANS_SUBR(8);
11334
11335         /* number of bytes for quota limit */
11336         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11337         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
11338         COUNT_BYTES_TRANS_SUBR(8);
11339
11340         /* one byte of quota flags */
11341         CHECK_BYTE_COUNT_TRANS_SUBR(1);
11342         dissect_quota_flags(tvb, tree, offset);
11343         COUNT_BYTES_TRANS_SUBR(1);
11344
11345         /* these 7 bytes are unknown */
11346         CHECK_BYTE_COUNT_TRANS_SUBR(7);
11347         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11348                     offset, 7, TRUE);
11349         COUNT_BYTES_TRANS_SUBR(7);
11350
11351         return offset;
11352 }
11353
11354 static int
11355 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
11356     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
11357 {
11358         proto_item *item = NULL;
11359         proto_tree *tree = NULL;
11360         smb_info_t *si;
11361
11362         si = (smb_info_t *)pinfo->private_data;
11363
11364         if(parent_tree){
11365                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
11366                                 "%s Data",
11367                                 val_to_str(subcmd, trans2_cmd_vals,
11368                                                 "Unknown (0x%02x)"));
11369                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
11370         }
11371
11372         switch(subcmd){
11373         case 0x00:      /*TRANS2_OPEN2*/
11374                 /* XXX dont know how to decode FEAList */
11375                 break;
11376         case 0x01:      /*TRANS2_FIND_FIRST2*/
11377                 /* XXX dont know how to decode FEAList */
11378                 break;
11379         case 0x02:      /*TRANS2_FIND_NEXT2*/
11380                 /* XXX dont know how to decode FEAList */
11381                 break;
11382         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
11383                 /* no data field in this request */
11384                 break;
11385         case 0x04:      /* TRANS2_SET_QUOTA */
11386                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
11387                 break;
11388         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
11389                 /* no data field in this request */
11390                 /*
11391                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11392                  * Extensions Version 3.0, Document Version 1.11,
11393                  * July 19, 1990" says there may be "Additional
11394                  * FileInfoLevel dependent information" here.
11395                  *
11396                  * Was that just a cut-and-pasteo?
11397                  * TRANS2_SET_PATH_INFORMATION *does* have that information
11398                  * here.
11399                  */
11400                 break;
11401         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
11402                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
11403                 break;
11404         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
11405                 /* no data field in this request */
11406                 /*
11407                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11408                  * Extensions Version 3.0, Document Version 1.11,
11409                  * July 19, 1990" says there may be "Additional
11410                  * FileInfoLevel dependent information" here.
11411                  *
11412                  * Was that just a cut-and-pasteo?
11413                  * TRANS2_SET_FILE_INFORMATION *does* have that information
11414                  * here.
11415                  */
11416                 break;
11417         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
11418                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
11419                 break;
11420         case 0x09:      /*TRANS2_FSCTL*/
11421                 /*XXX dont know how to decode this yet */
11422
11423                 /*
11424                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11425                  * Extensions Version 3.0, Document Version 1.11,
11426                  * July 19, 1990" says this this contains a
11427                  * "File system specific data block".  (That means we
11428                  * may not be able to dissect it in any case.)
11429                  */
11430                 break;
11431         case 0x0a:      /*TRANS2_IOCTL2*/
11432                 /*XXX dont know how to decode this yet */
11433
11434                 /*
11435                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11436                  * Extensions Version 3.0, Document Version 1.11,
11437                  * July 19, 1990" says this this contains a
11438                  * "Device/function specific data block".  (That
11439                  * means we may not be able to dissect it in any case.)
11440                  */
11441                 break;
11442         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11443                 /*XXX dont know how to decode this yet */
11444
11445                 /*
11446                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11447                  * Extensions Version 3.0, Document Version 1.11,
11448                  * July 19, 1990" says this this contains "additional
11449                  * level dependent match data".
11450                  */
11451                 break;
11452         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11453                 /*XXX dont know how to decode this yet */
11454
11455                 /*
11456                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11457                  * Extensions Version 3.0, Document Version 1.11,
11458                  * July 19, 1990" says this this contains "additional
11459                  * level dependent monitor information".
11460                  */
11461                 break;
11462         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11463                 /* XXX optional FEAList, unknown what FEAList looks like*/
11464                 break;
11465         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11466                 /*XXX dont know how to decode this yet */
11467                 break;
11468         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11469                 /* no data field in this request */
11470                 break;
11471         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11472                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
11473                 break;
11474         }
11475
11476         /* ooops there were data we didnt know how to process */
11477         if(dc != 0){
11478                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
11479                 offset += dc;
11480         }
11481
11482         return offset;
11483 }
11484
11485
11486 static void
11487 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
11488     proto_tree *tree)
11489 {
11490         int i;
11491         int offset;
11492         guint length;
11493
11494         /*
11495          * Show the setup words.
11496          */
11497         if (s_tvb != NULL) {
11498                 length = tvb_reported_length(s_tvb);
11499                 for (i = 0, offset = 0; length >= 2;
11500                     i++, offset += 2, length -= 2) {
11501                         /*
11502                          * XXX - add a setup word filterable field?
11503                          */
11504                         proto_tree_add_text(tree, s_tvb, offset, 2,
11505                             "Setup Word %d: 0x%04x", i,
11506                             tvb_get_letohs(s_tvb, offset));
11507                 }
11508         }
11509
11510         /*
11511          * Show the parameters, if any.
11512          */
11513         if (p_tvb != NULL) {
11514                 length = tvb_reported_length(p_tvb);
11515                 if (length != 0) {
11516                         proto_tree_add_text(tree, p_tvb, 0, length,
11517                             "Parameters: %s",
11518                             tvb_bytes_to_str(p_tvb, 0, length));
11519                 }
11520         }
11521
11522         /*
11523          * Show the data, if any.
11524          */
11525         if (d_tvb != NULL) {
11526                 length = tvb_reported_length(d_tvb);
11527                 if (length != 0) {
11528                         proto_tree_add_text(tree, d_tvb, 0, length,
11529                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
11530                 }
11531         }
11532 }
11533
11534 /* This routine handles the following 4 calls
11535    Transaction  0x25
11536    Transaction Secondary 0x26
11537    Transaction2 0x32
11538    Transaction2 Secondary 0x33
11539 */
11540 static int
11541 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
11542 {
11543         guint8 wc, sc=0;
11544         int so=offset;
11545         int sl=0;
11546         int spo=offset;
11547         int spc=0;
11548         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
11549         int subcmd = -1;
11550         guint32 to;
11551         int an_len;
11552         const char *an = NULL;
11553         smb_info_t *si;
11554         smb_transact2_info_t *t2i;
11555         smb_transact_info_t *tri;
11556         guint16 bc;
11557         int padcnt;
11558         gboolean dissected_trans;
11559
11560         si = (smb_info_t *)pinfo->private_data;
11561
11562         WORD_COUNT;
11563
11564         if(wc==8){
11565                 /*secondary client request*/
11566
11567                 /* total param count, only a 16bit integer here*/
11568                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11569                 offset += 2;
11570
11571                 /* total data count , only 16bit integer here*/
11572                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11573                 offset += 2;
11574
11575                 /* param count */
11576                 pc = tvb_get_letohs(tvb, offset);
11577                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11578                 offset += 2;
11579
11580                 /* param offset */
11581                 po = tvb_get_letohs(tvb, offset);
11582                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11583                 offset += 2;
11584
11585                 /* param disp */
11586                 pd = tvb_get_letohs(tvb, offset);
11587                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
11588                 offset += 2;
11589
11590                 /* data count */
11591                 dc = tvb_get_letohs(tvb, offset);
11592                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11593                 offset += 2;
11594
11595                 /* data offset */
11596                 od = tvb_get_letohs(tvb, offset);
11597                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11598                 offset += 2;
11599
11600                 /* data disp */
11601                 dd = tvb_get_letohs(tvb, offset);
11602                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
11603                 offset += 2;
11604
11605                 if(si->cmd==SMB_COM_TRANSACTION2){
11606                         guint16 fid;
11607
11608                         /* fid */
11609                         fid = tvb_get_letohs(tvb, offset);
11610                         add_fid(tvb, pinfo, tree, offset, 2, fid);
11611
11612                         offset += 2;
11613                 }
11614
11615                 /* There are no setup words. */
11616                 so = offset;
11617                 sc = 0;
11618                 sl = 0;
11619         } else {
11620                 /* it is not a secondary request */
11621
11622                 /* total param count , only a 16 bit integer here*/
11623                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11624                 offset += 2;
11625
11626                 /* total data count , only 16bit integer here*/
11627                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11628                 offset += 2;
11629
11630                 /* max param count , only 16bit integer here*/
11631                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11632                 offset += 2;
11633
11634                 /* max data count, only 16bit integer here*/
11635                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11636                 offset += 2;
11637
11638                 /* max setup count, only 16bit integer here*/
11639                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
11640                 offset += 1;
11641
11642                 /* reserved byte */
11643                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11644                 offset += 1;
11645
11646                 /* transaction flags */
11647                 tf = dissect_transaction_flags(tvb, tree, offset);
11648                 offset += 2;
11649
11650                 /* timeout */
11651                 to = tvb_get_letohl(tvb, offset);
11652                 if (to == 0)
11653                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
11654                 else if (to == 0xffffffff)
11655                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
11656                 else
11657                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
11658                 offset += 4;
11659
11660                 /* 2 reserved bytes */
11661                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
11662                 offset += 2;
11663
11664                 /* param count */
11665                 pc = tvb_get_letohs(tvb, offset);
11666                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11667                 offset += 2;
11668
11669                 /* param offset */
11670                 po = tvb_get_letohs(tvb, offset);
11671                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11672                 offset += 2;
11673
11674                 /* param displacement is zero here */
11675                 pd = 0;
11676
11677                 /* data count */
11678                 dc = tvb_get_letohs(tvb, offset);
11679                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11680                 offset += 2;
11681
11682                 /* data offset */
11683                 od = tvb_get_letohs(tvb, offset);
11684                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11685                 offset += 2;
11686
11687                 /* data displacement is zero here */
11688                 dd = 0;
11689
11690                 /* setup count */
11691                 sc = tvb_get_guint8(tvb, offset);
11692                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
11693                 offset += 1;
11694
11695                 /* reserved byte */
11696                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11697                 offset += 1;
11698
11699                 /* this is where the setup bytes, if any start */
11700                 so = offset;
11701                 sl = sc*2;
11702
11703                 /* if there were any setup bytes, decode them */
11704                 if(sc){
11705                         switch(si->cmd){
11706
11707                         case SMB_COM_TRANSACTION2:
11708                                 /* TRANSACTION2 only has one setup word and
11709                                    that is the subcommand code.
11710
11711                                    XXX - except for TRANS2_FSCTL
11712                                    and TRANS2_IOCTL. */
11713                                 subcmd = tvb_get_letohs(tvb, offset);
11714                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
11715                                     tvb, offset, 2, subcmd);
11716                                 if (check_col(pinfo->cinfo, COL_INFO)) {
11717                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11718                                             val_to_str(subcmd, trans2_cmd_vals,
11719                                                 "Unknown (0x%02x)"));
11720                                 }
11721                                 if (!si->unidir) {
11722                                         if(!pinfo->fd->flags.visited){
11723                                                 /*
11724                                                  * Allocate a new
11725                                                  * smb_transact2_info_t
11726                                                  * structure.
11727                                                  */
11728                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
11729                                                 t2i->subcmd = subcmd;
11730                                                 t2i->info_level = -1;
11731                                                 t2i->resume_keys = FALSE;
11732                                                 si->sip->extra_info = t2i;
11733                                         }
11734                                 }
11735
11736                                 /*
11737                                  * XXX - process TRANS2_FSCTL and
11738                                  * TRANS2_IOCTL setup words here.
11739                                  */
11740                                 break;
11741
11742                         case SMB_COM_TRANSACTION:
11743                                 /* TRANSACTION setup words processed below */
11744                                 break;
11745                         }
11746
11747                         offset += sl;
11748                 }
11749         }
11750
11751         BYTE_COUNT;
11752
11753         if(wc!=8){
11754                 /* primary request */
11755                 /* name is NULL if transaction2 */
11756                 if(si->cmd == SMB_COM_TRANSACTION){
11757                         /* Transaction Name */
11758                         an = get_unicode_or_ascii_string(tvb, &offset,
11759                                 si->unicode, &an_len, FALSE, FALSE, &bc);
11760                         if (an == NULL)
11761                                 goto endofcommand;
11762                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
11763                                 offset, an_len, an);
11764                         COUNT_BYTES(an_len);
11765                 }
11766         }
11767
11768         /*
11769          * The pipe or mailslot arguments for Transaction start with
11770          * the first setup word (or where the first setup word would
11771          * be if there were any setup words), and run to the current
11772          * offset (which could mean that there aren't any).
11773          */
11774         spo = so;
11775         spc = offset - spo;
11776
11777         /* parameters */
11778         if(po>offset){
11779                 /* We have some initial padding bytes.
11780                 */
11781                 padcnt = po-offset;
11782                 if (padcnt > bc)
11783                         padcnt = bc;
11784                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11785                 COUNT_BYTES(padcnt);
11786         }
11787         if(pc){
11788                 CHECK_BYTE_COUNT(pc);
11789                 switch(si->cmd) {
11790
11791                 case SMB_COM_TRANSACTION2:
11792                         /* TRANSACTION2 parameters*/
11793                         offset = dissect_transaction2_request_parameters(tvb,
11794                             pinfo, tree, offset, subcmd, pc);
11795                         bc -= pc;
11796                         break;
11797
11798                 case SMB_COM_TRANSACTION:
11799                         /* TRANSACTION parameters processed below */
11800                         COUNT_BYTES(pc);
11801                         break;
11802                 }
11803         }
11804
11805         /* data */
11806         if(od>offset){
11807                 /* We have some initial padding bytes.
11808                 */
11809                 padcnt = od-offset;
11810                 if (padcnt > bc)
11811                         padcnt = bc;
11812                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11813                 COUNT_BYTES(padcnt);
11814         }
11815         if(dc){
11816                 CHECK_BYTE_COUNT(dc);
11817                 switch(si->cmd){
11818
11819                 case SMB_COM_TRANSACTION2:
11820                         /* TRANSACTION2 data*/
11821                         offset = dissect_transaction2_request_data(tvb, pinfo,
11822                             tree, offset, subcmd, dc);
11823                         bc -= dc;
11824                         break;
11825
11826                 case SMB_COM_TRANSACTION:
11827                         /* TRANSACTION data processed below */
11828                         COUNT_BYTES(dc);
11829                         break;
11830                 }
11831         }
11832
11833         /*TRANSACTION request parameters */
11834         if(si->cmd==SMB_COM_TRANSACTION){
11835                 /*XXX replace this block with a function and use that one
11836                      for both requests/responses*/
11837                 if(dd==0){
11838                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
11839                         tvbuff_t *sp_tvb, *pd_tvb;
11840
11841                         if(pc>0){
11842                                 if(pc>tvb_length_remaining(tvb, po)){
11843                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
11844                                 } else {
11845                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
11846                                 }
11847                         } else {
11848                                 p_tvb = NULL;
11849                         }
11850                         if(dc>0){
11851                                 if(dc>tvb_length_remaining(tvb, od)){
11852                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
11853                                 } else {
11854                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
11855                                 }
11856                         } else {
11857                                 d_tvb = NULL;
11858                         }
11859                         if(sl){
11860                                 if(sl>tvb_length_remaining(tvb, so)){
11861                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
11862                                 } else {
11863                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
11864                                 }
11865                         } else {
11866                                 s_tvb = NULL;
11867                         }
11868
11869                         if (!si->unidir) {
11870                                 if(!pinfo->fd->flags.visited){
11871                                         /*
11872                                          * Allocate a new smb_transact_info_t
11873                                          * structure.
11874                                          */
11875                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
11876                                         tri->subcmd = -1;
11877                                         tri->trans_subcmd = -1;
11878                                         tri->function = -1;
11879                                         tri->fid = -1;
11880                                         tri->lanman_cmd = 0;
11881                                         tri->param_descrip = NULL;
11882                                         tri->data_descrip = NULL;
11883                                         tri->aux_data_descrip = NULL;
11884                                         tri->info_level = -1;
11885                                         si->sip->extra_info = tri;
11886                                 } else {
11887                                         /*
11888                                          * We already filled the structure
11889                                          * in; don't bother doing so again.
11890                                          */
11891                                         tri = NULL;
11892                                 }
11893                         } else {
11894                                 /*
11895                                  * This is a unidirectional message, for
11896                                  * which there will be no reply; don't
11897                                  * bother allocating an "smb_transact_info_t"
11898                                  * structure for it.
11899                                  */
11900                                 tri = NULL;
11901                         }
11902                         dissected_trans = FALSE;
11903                         if(strncmp("\\PIPE\\", an, 6) == 0){
11904                                 if (tri != NULL)
11905                                         tri->subcmd=TRANSACTION_PIPE;
11906
11907                                 /*
11908                                  * A tvbuff containing the setup words and
11909                                  * the pipe path.
11910                                  */
11911                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
11912
11913                                 /*
11914                                  * A tvbuff containing the parameters and the
11915                                  * data.
11916                                  */
11917                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
11918
11919                                 dissected_trans = dissect_pipe_smb(sp_tvb,
11920                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
11921                                     top_tree);
11922
11923                                 /* In case we did not see the TreeConnect call,
11924                                    store this TID here as well as a IPC TID 
11925                                    so we know that future Read/Writes to this 
11926                                    TID is (probably) DCERPC.
11927                                 */
11928                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
11929                                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
11930                                 }
11931                                 g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
11932                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
11933                                 if (tri != NULL)
11934                                         tri->subcmd=TRANSACTION_MAILSLOT;
11935
11936                                 /*
11937                                  * A tvbuff containing the setup words and
11938                                  * the mailslot path.
11939                                  */
11940                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
11941                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
11942                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
11943                         }
11944                         if (!dissected_trans)
11945                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
11946                 } else {
11947                         if(check_col(pinfo->cinfo, COL_INFO)){
11948                                 col_append_str(pinfo->cinfo, COL_INFO,
11949                                         "[transact continuation]");
11950                         }
11951                 }
11952         }
11953
11954         END_OF_SMB
11955
11956         return offset;
11957 }
11958
11959
11960
11961 static int
11962 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11963     int offset, guint16 *bcp, gboolean *trunc)
11964 {
11965         int fn_len;
11966         const char *fn;
11967         int old_offset = offset;
11968         proto_item *item = NULL;
11969         proto_tree *tree = NULL;
11970         smb_info_t *si;
11971         smb_transact2_info_t *t2i;
11972         gboolean resume_keys = FALSE;
11973
11974         si = (smb_info_t *)pinfo->private_data;
11975         if (si->sip != NULL) {
11976                 t2i = si->sip->extra_info;
11977                 if (t2i != NULL)
11978                         resume_keys = t2i->resume_keys;
11979         }
11980
11981         if(parent_tree){
11982                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11983                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11984                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11985         }
11986
11987         if (resume_keys) {
11988                 /* resume key */
11989                 CHECK_BYTE_COUNT_SUBR(4);
11990                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
11991                 COUNT_BYTES_SUBR(4);
11992         }
11993
11994         /* create time */
11995         CHECK_BYTE_COUNT_SUBR(4);
11996         offset = dissect_smb_datetime(tvb, tree, offset,
11997                 hf_smb_create_time,
11998                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
11999         *bcp -= 4;
12000
12001         /* access time */
12002         CHECK_BYTE_COUNT_SUBR(4);
12003         offset = dissect_smb_datetime(tvb, tree, offset,
12004                 hf_smb_access_time,
12005                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
12006         *bcp -= 4;
12007
12008         /* last write time */
12009         CHECK_BYTE_COUNT_SUBR(4);
12010         offset = dissect_smb_datetime(tvb, tree, offset,
12011                 hf_smb_last_write_time,
12012                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
12013         *bcp -= 4;
12014
12015         /* data size */
12016         CHECK_BYTE_COUNT_SUBR(4);
12017         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12018         COUNT_BYTES_SUBR(4);
12019
12020         /* allocation size */
12021         CHECK_BYTE_COUNT_SUBR(4);
12022         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
12023         COUNT_BYTES_SUBR(4);
12024
12025         /* File Attributes */
12026         CHECK_BYTE_COUNT_SUBR(2);
12027         offset = dissect_file_attributes(tvb, tree, offset, 2);
12028         *bcp -= 2;
12029
12030         /* file name len */
12031         CHECK_BYTE_COUNT_SUBR(1);
12032         fn_len = tvb_get_guint8(tvb, offset);
12033         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
12034         COUNT_BYTES_SUBR(1);
12035         if (si->unicode)
12036                 fn_len += 2;    /* include terminating '\0' */
12037         else
12038                 fn_len++;       /* include terminating '\0' */
12039
12040         /* file name */
12041         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12042         CHECK_STRING_SUBR(fn);
12043         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12044                 fn);
12045         COUNT_BYTES_SUBR(fn_len);
12046
12047         if (check_col(pinfo->cinfo, COL_INFO)) {
12048                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12049                 fn);
12050         }
12051
12052         proto_item_append_text(item, " File: %s", fn);
12053         proto_item_set_len(item, offset-old_offset);
12054
12055         *trunc = FALSE;
12056         return offset;
12057 }
12058
12059 static int
12060 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12061     int offset, guint16 *bcp, gboolean *trunc)
12062 {
12063         int fn_len;
12064         const char *fn;
12065         int old_offset = offset;
12066         proto_item *item = NULL;
12067         proto_tree *tree = NULL;
12068         smb_info_t *si;
12069         smb_transact2_info_t *t2i;
12070         gboolean resume_keys = FALSE;
12071
12072         si = (smb_info_t *)pinfo->private_data;
12073         if (si->sip != NULL) {
12074                 t2i = si->sip->extra_info;
12075                 if (t2i != NULL)
12076                         resume_keys = t2i->resume_keys;
12077         }
12078
12079         if(parent_tree){
12080                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12081                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12082                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12083         }
12084
12085         if (resume_keys) {
12086                 /* resume key */
12087                 CHECK_BYTE_COUNT_SUBR(4);
12088                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
12089                 COUNT_BYTES_SUBR(4);
12090         }
12091
12092         /* create time */
12093         CHECK_BYTE_COUNT_SUBR(4);
12094         offset = dissect_smb_datetime(tvb, tree, offset,
12095                 hf_smb_create_time,
12096                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
12097         *bcp -= 4;
12098
12099         /* access time */
12100         CHECK_BYTE_COUNT_SUBR(4);
12101         offset = dissect_smb_datetime(tvb, tree, offset,
12102                 hf_smb_access_time,
12103                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
12104         *bcp -= 4;
12105
12106         /* last write time */
12107         CHECK_BYTE_COUNT_SUBR(4);
12108         offset = dissect_smb_datetime(tvb, tree, offset,
12109                 hf_smb_last_write_time,
12110                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
12111         *bcp -= 4;
12112
12113         /* data size */
12114         CHECK_BYTE_COUNT_SUBR(4);
12115         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12116         COUNT_BYTES_SUBR(4);
12117
12118         /* allocation size */
12119         CHECK_BYTE_COUNT_SUBR(4);
12120         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
12121         COUNT_BYTES_SUBR(4);
12122
12123         /* File Attributes */
12124         CHECK_BYTE_COUNT_SUBR(2);
12125         offset = dissect_file_attributes(tvb, tree, offset, 2);
12126         *bcp -= 2;
12127
12128         /* ea length */
12129         CHECK_BYTE_COUNT_SUBR(4);
12130         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12131         COUNT_BYTES_SUBR(4);
12132
12133         /* file name len */
12134         CHECK_BYTE_COUNT_SUBR(1);
12135         fn_len = tvb_get_guint8(tvb, offset);
12136         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
12137         COUNT_BYTES_SUBR(1);
12138         if (si->unicode)
12139                 fn_len += 2;    /* include terminating '\0' */
12140         else
12141                 fn_len++;       /* include terminating '\0' */
12142
12143         /* file name */
12144         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12145         CHECK_STRING_SUBR(fn);
12146         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12147                 fn);
12148         COUNT_BYTES_SUBR(fn_len);
12149
12150         if (check_col(pinfo->cinfo, COL_INFO)) {
12151                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12152                 fn);
12153         }
12154
12155         proto_item_append_text(item, " File: %s", fn);
12156         proto_item_set_len(item, offset-old_offset);
12157
12158         *trunc = FALSE;
12159         return offset;
12160 }
12161
12162 static int
12163 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12164     int offset, guint16 *bcp, gboolean *trunc)
12165 {
12166         int fn_len;
12167         const char *fn;
12168         int old_offset = offset;
12169         proto_item *item = NULL;
12170         proto_tree *tree = NULL;
12171         smb_info_t *si;
12172         guint32 neo;
12173         int padcnt;
12174
12175         si = (smb_info_t *)pinfo->private_data;
12176
12177         if(parent_tree){
12178                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12179                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12180                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12181         }
12182
12183         /*
12184          * We assume that the presence of a next entry offset implies the
12185          * absence of a resume key, as appears to be the case for 4.3.4.6.
12186          */
12187
12188         /* next entry offset */
12189         CHECK_BYTE_COUNT_SUBR(4);
12190         neo = tvb_get_letohl(tvb, offset);
12191         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12192         COUNT_BYTES_SUBR(4);
12193
12194         /* file index */
12195         CHECK_BYTE_COUNT_SUBR(4);
12196         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12197         COUNT_BYTES_SUBR(4);
12198
12199         /* create time */
12200         CHECK_BYTE_COUNT_SUBR(8);
12201         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12202         *bcp -= 8;
12203
12204         /* access time */
12205         CHECK_BYTE_COUNT_SUBR(8);
12206         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12207         *bcp -= 8;
12208
12209         /* last write time */
12210         CHECK_BYTE_COUNT_SUBR(8);
12211         offset = dissect_smb_64bit_time(tvb, tree, offset,
12212                 hf_smb_last_write_time);
12213         *bcp -= 8;
12214
12215         /* last change time */
12216         CHECK_BYTE_COUNT_SUBR(8);
12217         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12218         *bcp -= 8;
12219
12220         /* end of file */
12221         CHECK_BYTE_COUNT_SUBR(8);
12222         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12223         COUNT_BYTES_SUBR(8);
12224
12225         /* allocation size */
12226         CHECK_BYTE_COUNT_SUBR(8);
12227         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12228         COUNT_BYTES_SUBR(8);
12229
12230         /* Extended File Attributes */
12231         CHECK_BYTE_COUNT_SUBR(4);
12232         offset = dissect_file_ext_attr(tvb, tree, offset);
12233         *bcp -= 4;
12234
12235         /* file name len */
12236         CHECK_BYTE_COUNT_SUBR(4);
12237         fn_len = tvb_get_letohl(tvb, offset);
12238         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12239         COUNT_BYTES_SUBR(4);
12240
12241         /* file name */
12242         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12243         CHECK_STRING_SUBR(fn);
12244         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12245                 fn);
12246         COUNT_BYTES_SUBR(fn_len);
12247
12248         if (check_col(pinfo->cinfo, COL_INFO)) {
12249                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12250                 fn);
12251         }
12252
12253         /* skip to next structure */
12254         if(neo){
12255                 padcnt = (old_offset + neo) - offset;
12256                 if (padcnt < 0) {
12257                         /*
12258                          * XXX - this is bogus; flag it?
12259                          */
12260                         padcnt = 0;
12261                 }
12262                 if (padcnt != 0) {
12263                         CHECK_BYTE_COUNT_SUBR(padcnt);
12264                         COUNT_BYTES_SUBR(padcnt);
12265                 }
12266         }
12267
12268         proto_item_append_text(item, " File: %s", fn);
12269         proto_item_set_len(item, offset-old_offset);
12270
12271         *trunc = FALSE;
12272         return offset;
12273 }
12274
12275 static int
12276 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12277     int offset, guint16 *bcp, gboolean *trunc)
12278 {
12279         int fn_len;
12280         const char *fn;
12281         int old_offset = offset;
12282         proto_item *item = NULL;
12283         proto_tree *tree = NULL;
12284         smb_info_t *si;
12285         guint32 neo;
12286         int padcnt;
12287
12288         si = (smb_info_t *)pinfo->private_data;
12289
12290         if(parent_tree){
12291                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12292                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12293                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12294         }
12295
12296         /*
12297          * We assume that the presence of a next entry offset implies the
12298          * absence of a resume key, as appears to be the case for 4.3.4.6.
12299          */
12300
12301         /* next entry offset */
12302         CHECK_BYTE_COUNT_SUBR(4);
12303         neo = tvb_get_letohl(tvb, offset);
12304         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12305         COUNT_BYTES_SUBR(4);
12306
12307         /* file index */
12308         CHECK_BYTE_COUNT_SUBR(4);
12309         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12310         COUNT_BYTES_SUBR(4);
12311
12312         /* create time */
12313         CHECK_BYTE_COUNT_SUBR(8);
12314         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12315         *bcp -= 8;
12316
12317         /* access time */
12318         CHECK_BYTE_COUNT_SUBR(8);
12319         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12320         *bcp -= 8;
12321
12322         /* last write time */
12323         CHECK_BYTE_COUNT_SUBR(8);
12324         offset = dissect_smb_64bit_time(tvb, tree, offset,
12325                 hf_smb_last_write_time);
12326         *bcp -= 8;
12327
12328         /* last change time */
12329         CHECK_BYTE_COUNT_SUBR(8);
12330         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12331         *bcp -= 8;
12332
12333         /* end of file */
12334         CHECK_BYTE_COUNT_SUBR(8);
12335         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12336         COUNT_BYTES_SUBR(8);
12337
12338         /* allocation size */
12339         CHECK_BYTE_COUNT_SUBR(8);
12340         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12341         COUNT_BYTES_SUBR(8);
12342
12343         /* Extended File Attributes */
12344         CHECK_BYTE_COUNT_SUBR(4);
12345         offset = dissect_file_ext_attr(tvb, tree, offset);
12346         *bcp -= 4;
12347
12348         /* file name len */
12349         CHECK_BYTE_COUNT_SUBR(4);
12350         fn_len = tvb_get_letohl(tvb, offset);
12351         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12352         COUNT_BYTES_SUBR(4);
12353
12354         /* ea length */
12355         CHECK_BYTE_COUNT_SUBR(4);
12356         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12357         COUNT_BYTES_SUBR(4);
12358
12359         /* file name */
12360         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12361         CHECK_STRING_SUBR(fn);
12362         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12363                 fn);
12364         COUNT_BYTES_SUBR(fn_len);
12365
12366         if (check_col(pinfo->cinfo, COL_INFO)) {
12367                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12368                 fn);
12369         }
12370
12371         /* skip to next structure */
12372         if(neo){
12373                 padcnt = (old_offset + neo) - offset;
12374                 if (padcnt < 0) {
12375                         /*
12376                          * XXX - this is bogus; flag it?
12377                          */
12378                         padcnt = 0;
12379                 }
12380                 if (padcnt != 0) {
12381                         CHECK_BYTE_COUNT_SUBR(padcnt);
12382                         COUNT_BYTES_SUBR(padcnt);
12383                 }
12384         }
12385
12386         proto_item_append_text(item, " File: %s", fn);
12387         proto_item_set_len(item, offset-old_offset);
12388
12389         *trunc = FALSE;
12390         return offset;
12391 }
12392
12393 static int
12394 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12395     int offset, guint16 *bcp, gboolean *trunc)
12396 {
12397         int fn_len, sfn_len;
12398         const char *fn, *sfn;
12399         int old_offset = offset;
12400         proto_item *item = NULL;
12401         proto_tree *tree = NULL;
12402         smb_info_t *si;
12403         guint32 neo;
12404         int padcnt;
12405
12406         si = (smb_info_t *)pinfo->private_data;
12407
12408         if(parent_tree){
12409                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12410                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12411                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12412         }
12413
12414         /*
12415          * XXX - I have not seen any of these that contain a resume
12416          * key, even though some of the requests had the "return resume
12417          * key" flag set.
12418          */
12419
12420         /* next entry offset */
12421         CHECK_BYTE_COUNT_SUBR(4);
12422         neo = tvb_get_letohl(tvb, offset);
12423         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12424         COUNT_BYTES_SUBR(4);
12425
12426         /* file index */
12427         CHECK_BYTE_COUNT_SUBR(4);
12428         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12429         COUNT_BYTES_SUBR(4);
12430
12431         /* create time */
12432         CHECK_BYTE_COUNT_SUBR(8);
12433         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12434         *bcp -= 8;
12435
12436         /* access time */
12437         CHECK_BYTE_COUNT_SUBR(8);
12438         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12439         *bcp -= 8;
12440
12441         /* last write time */
12442         CHECK_BYTE_COUNT_SUBR(8);
12443         offset = dissect_smb_64bit_time(tvb, tree, offset,
12444                 hf_smb_last_write_time);
12445         *bcp -= 8;
12446
12447         /* last change time */
12448         CHECK_BYTE_COUNT_SUBR(8);
12449         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12450         *bcp -= 8;
12451
12452         /* end of file */
12453         CHECK_BYTE_COUNT_SUBR(8);
12454         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12455         COUNT_BYTES_SUBR(8);
12456
12457         /* allocation size */
12458         CHECK_BYTE_COUNT_SUBR(8);
12459         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12460         COUNT_BYTES_SUBR(8);
12461
12462         /* Extended File Attributes */
12463         CHECK_BYTE_COUNT_SUBR(4);
12464         offset = dissect_file_ext_attr(tvb, tree, offset);
12465         *bcp -= 4;
12466
12467         /* file name len */
12468         CHECK_BYTE_COUNT_SUBR(4);
12469         fn_len = tvb_get_letohl(tvb, offset);
12470         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12471         COUNT_BYTES_SUBR(4);
12472
12473         /*
12474          * EA length.
12475          *
12476          * XXX - in one captures, this has the topmost bit set, and the
12477          * rest of the bits have the value 7.  Is the topmost bit being
12478          * set some indication that the value *isn't* the length of
12479          * the EAs?
12480          */
12481         CHECK_BYTE_COUNT_SUBR(4);
12482         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12483         COUNT_BYTES_SUBR(4);
12484
12485         /* short file name len */
12486         CHECK_BYTE_COUNT_SUBR(1);
12487         sfn_len = tvb_get_guint8(tvb, offset);
12488         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
12489         COUNT_BYTES_SUBR(1);
12490
12491         /* reserved byte */
12492         CHECK_BYTE_COUNT_SUBR(1);
12493         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12494         COUNT_BYTES_SUBR(1);
12495
12496         /* short file name */
12497         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
12498         CHECK_STRING_SUBR(sfn);
12499         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
12500                 sfn);
12501         COUNT_BYTES_SUBR(24);
12502
12503         /* file name */
12504         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12505         CHECK_STRING_SUBR(fn);
12506         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12507                 fn);
12508         COUNT_BYTES_SUBR(fn_len);
12509
12510         if (check_col(pinfo->cinfo, COL_INFO)) {
12511                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12512                 fn);
12513         }
12514
12515         /* skip to next structure */
12516         if(neo){
12517                 padcnt = (old_offset + neo) - offset;
12518                 if (padcnt < 0) {
12519                         /*
12520                          * XXX - this is bogus; flag it?
12521                          */
12522                         padcnt = 0;
12523                 }
12524                 if (padcnt != 0) {
12525                         CHECK_BYTE_COUNT_SUBR(padcnt);
12526                         COUNT_BYTES_SUBR(padcnt);
12527                 }
12528         }
12529
12530         proto_item_append_text(item, " File: %s", fn);
12531         proto_item_set_len(item, offset-old_offset);
12532
12533         *trunc = FALSE;
12534         return offset;
12535 }
12536
12537 static int
12538 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12539     int offset, guint16 *bcp, gboolean *trunc)
12540 {
12541         int fn_len;
12542         const char *fn;
12543         int old_offset = offset;
12544         proto_item *item = NULL;
12545         proto_tree *tree = NULL;
12546         smb_info_t *si;
12547         guint32 neo;
12548         int padcnt;
12549
12550         si = (smb_info_t *)pinfo->private_data;
12551
12552         if(parent_tree){
12553                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12554                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12555                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12556         }
12557
12558         /*
12559          * We assume that the presence of a next entry offset implies the
12560          * absence of a resume key, as appears to be the case for 4.3.4.6.
12561          */
12562
12563         /* next entry offset */
12564         CHECK_BYTE_COUNT_SUBR(4);
12565         neo = tvb_get_letohl(tvb, offset);
12566         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12567         COUNT_BYTES_SUBR(4);
12568
12569         /* file index */
12570         CHECK_BYTE_COUNT_SUBR(4);
12571         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12572         COUNT_BYTES_SUBR(4);
12573
12574         /* file name len */
12575         CHECK_BYTE_COUNT_SUBR(4);
12576         fn_len = tvb_get_letohl(tvb, offset);
12577         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12578         COUNT_BYTES_SUBR(4);
12579
12580         /* file name */
12581         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12582         CHECK_STRING_SUBR(fn);
12583         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12584                 fn);
12585         COUNT_BYTES_SUBR(fn_len);
12586
12587         if (check_col(pinfo->cinfo, COL_INFO)) {
12588                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12589                 fn);
12590         }
12591
12592         /* skip to next structure */
12593         if(neo){
12594                 padcnt = (old_offset + neo) - offset;
12595                 if (padcnt < 0) {
12596                         /*
12597                          * XXX - this is bogus; flag it?
12598                          */
12599                         padcnt = 0;
12600                 }
12601                 if (padcnt != 0) {
12602                         CHECK_BYTE_COUNT_SUBR(padcnt);
12603                         COUNT_BYTES_SUBR(padcnt);
12604                 }
12605         }
12606
12607         proto_item_append_text(item, " File: %s", fn);
12608         proto_item_set_len(item, offset-old_offset);
12609
12610         *trunc = FALSE;
12611         return offset;
12612 }
12613
12614 static int
12615 dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
12616                 proto_tree *parent_tree _U_, int offset, guint16 *bcp,
12617                 gboolean *trunc)
12618 {
12619 /*XXX im lazy. i havnt implemented this */
12620         offset += *bcp;
12621         *bcp = 0;
12622         *trunc = FALSE;
12623         return offset;
12624 }
12625
12626 /*dissect the data block for TRANS2_FIND_FIRST2*/
12627 static int
12628 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
12629     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
12630 {
12631         smb_info_t *si;
12632
12633         if(!*bcp){
12634                 return offset;
12635         }
12636
12637         si = (smb_info_t *)pinfo->private_data;
12638         switch(si->info_level){
12639         case 1:         /*Info Standard*/
12640                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
12641                     trunc);
12642                 break;
12643         case 2:         /*Info Query EA Size*/
12644                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
12645                     trunc);
12646                 break;
12647         case 3:         /*Info Query EAs From List same as
12648                                 InfoQueryEASize*/
12649                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
12650                     trunc);
12651                 break;
12652         case 0x0101:    /*Find File Directory Info*/
12653                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
12654                     trunc);
12655                 break;
12656         case 0x0102:    /*Find File Full Directory Info*/
12657                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
12658                     trunc);
12659                 break;
12660         case 0x0103:    /*Find File Names Info*/
12661                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
12662                     trunc);
12663                 break;
12664         case 0x0104:    /*Find File Both Directory Info*/
12665                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
12666                     trunc);
12667                 break;
12668         case 0x0202:    /*Find File UNIX*/
12669                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
12670                     trunc);
12671                 break;
12672         default:        /* unknown info level */
12673                 *trunc = FALSE;
12674                 break;
12675         }
12676         return offset;
12677 }
12678
12679
12680 static int
12681 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12682 {
12683         guint32 mask;
12684         proto_item *item = NULL;
12685         proto_tree *tree = NULL;
12686
12687         mask = tvb_get_letohl(tvb, offset);
12688
12689         if(parent_tree){
12690                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
12691                         "FS Attributes: 0x%08x", mask);
12692                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
12693         }
12694
12695         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
12696                 tvb, offset, 4, mask);
12697         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
12698                 tvb, offset, 4, mask);
12699         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
12700                 tvb, offset, 4, mask);
12701         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
12702                 tvb, offset, 4, mask);
12703         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
12704                 tvb, offset, 4, mask);
12705         proto_tree_add_boolean(tree, hf_smb_fs_attr_dim,
12706                 tvb, offset, 4, mask);
12707         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
12708                 tvb, offset, 4, mask);
12709
12710         offset += 4;
12711         return offset;
12712 }
12713
12714
12715 static int
12716 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12717 {
12718         guint32 mask;
12719         proto_item *item = NULL;
12720         proto_tree *tree = NULL;
12721
12722         mask = tvb_get_letohl(tvb, offset);
12723
12724         if(parent_tree){
12725                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
12726                         "Device Characteristics: 0x%08x", mask);
12727                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
12728         }
12729
12730         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
12731                 tvb, offset, 4, mask);
12732         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
12733                 tvb, offset, 4, mask);
12734         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
12735                 tvb, offset, 4, mask);
12736         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
12737                 tvb, offset, 4, mask);
12738         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
12739                 tvb, offset, 4, mask);
12740         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
12741                 tvb, offset, 4, mask);
12742         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
12743                 tvb, offset, 4, mask);
12744
12745         offset += 4;
12746         return offset;
12747 }
12748
12749 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
12750
12751 static const true_false_string tfs_smb_mac_access_ctrl = {
12752   "Macintosh Access Control Supported",
12753   "Macintosh Access Control Not Supported"
12754 };
12755
12756 static const true_false_string tfs_smb_mac_getset_comments = {
12757   "Macintosh Get & Set Comments Supported",
12758   "Macintosh Get & Set Comments Not Supported"
12759 };
12760
12761 static const true_false_string tfs_smb_mac_desktopdb_calls = {
12762   "Macintosh Get & Set Desktop Database Info Supported",
12763   "Macintosh Get & Set Desktop Database Info Supported"
12764 };
12765
12766 static const true_false_string tfs_smb_mac_unique_ids = {
12767   "Macintosh Unique IDs Supported",
12768   "Macintosh Unique IDs Not Supported"
12769 };
12770
12771 static const true_false_string tfs_smb_mac_streams = {
12772   "Macintosh and Streams Extensions Not Supported",
12773   "Macintosh and Streams Extensions Supported"
12774 };
12775
12776 static int
12777 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
12778     int offset, guint16 *bcp)
12779 {
12780         smb_info_t *si;
12781         int fn_len, vll, fnl;
12782         const char *fn;
12783         guint support = 0;
12784         proto_item *item = NULL;
12785         proto_tree *ti = NULL;
12786
12787         if(!*bcp){
12788                 return offset;
12789         }
12790
12791         si = (smb_info_t *)pinfo->private_data;
12792         switch(si->info_level){
12793         case 1:         /* SMB_INFO_ALLOCATION */
12794                 /* filesystem id */
12795                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12796                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
12797                 COUNT_BYTES_TRANS_SUBR(4);
12798
12799                 /* sectors per unit */
12800                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12801                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12802                 COUNT_BYTES_TRANS_SUBR(4);
12803
12804                 /* units */
12805                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12806                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
12807                 COUNT_BYTES_TRANS_SUBR(4);
12808
12809                 /* avail units */
12810                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12811                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
12812                 COUNT_BYTES_TRANS_SUBR(4);
12813
12814                 /* bytes per sector, only 16bit integer here */
12815                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
12816                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12817                 COUNT_BYTES_TRANS_SUBR(2);
12818
12819                 break;
12820         case 2:         /* SMB_INFO_VOLUME */
12821                 /* volume serial number */
12822                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12823                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
12824                 COUNT_BYTES_TRANS_SUBR(4);
12825
12826                 /* volume label length, only one byte here */
12827                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
12828                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
12829                 COUNT_BYTES_TRANS_SUBR(1);
12830
12831                 /* label */
12832                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
12833                 CHECK_STRING_TRANS_SUBR(fn);
12834                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12835                         fn);
12836                 COUNT_BYTES_TRANS_SUBR(fn_len);
12837
12838                 break;
12839         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
12840         case 1001:      /* SMB_FS_LABEL_INFORMATION */
12841                 /* volume label length */
12842                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12843                 vll = tvb_get_letohl(tvb, offset);
12844                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
12845                 COUNT_BYTES_TRANS_SUBR(4);
12846
12847                 /* label */
12848                 fn_len = vll;
12849                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12850                 CHECK_STRING_TRANS_SUBR(fn);
12851                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12852                         fn);
12853                 COUNT_BYTES_TRANS_SUBR(fn_len);
12854
12855                 break;
12856         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
12857         case 1002:      /* SMB_FS_VOLUME_INFORMATION */
12858                 /* create time */
12859                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12860                 offset = dissect_smb_64bit_time(tvb, tree, offset,
12861                         hf_smb_create_time);
12862                 *bcp -= 8;
12863
12864                 /* volume serial number */
12865                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12866                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
12867                 COUNT_BYTES_TRANS_SUBR(4);
12868
12869                 /* volume label length */
12870                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12871                 vll = tvb_get_letohl(tvb, offset);
12872                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
12873                 COUNT_BYTES_TRANS_SUBR(4);
12874
12875                 /* 2 reserved bytes */
12876                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
12877                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
12878                 COUNT_BYTES_TRANS_SUBR(2);
12879
12880                 /* label */
12881                 fn_len = vll;
12882                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12883                 CHECK_STRING_TRANS_SUBR(fn);
12884                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12885                         fn);
12886                 COUNT_BYTES_TRANS_SUBR(fn_len);
12887
12888                 break;
12889         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
12890         case 1003:      /* SMB_FS_SIZE_INFORMATION */
12891                 /* allocation size */
12892                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12893                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12894                 COUNT_BYTES_TRANS_SUBR(8);
12895
12896                 /* free allocation units */
12897                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12898                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
12899                 COUNT_BYTES_TRANS_SUBR(8);
12900
12901                 /* sectors per unit */
12902                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12903                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12904                 COUNT_BYTES_TRANS_SUBR(4);
12905
12906                 /* bytes per sector */
12907                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12908                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
12909                 COUNT_BYTES_TRANS_SUBR(4);
12910
12911                 break;
12912         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
12913         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
12914                 /* device type */
12915                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12916                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
12917                 COUNT_BYTES_TRANS_SUBR(4);
12918
12919                 /* device characteristics */
12920                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12921                 offset = dissect_device_characteristics(tvb, tree, offset);
12922                 *bcp -= 4;
12923
12924                 break;
12925         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
12926         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
12927                 /* FS attributes */
12928                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12929                 offset = dissect_fs_attributes(tvb, tree, offset);
12930                 *bcp -= 4;
12931
12932                 /* max name len */
12933                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12934                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
12935                 COUNT_BYTES_TRANS_SUBR(4);
12936
12937                 /* fs name length */
12938                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12939                 fnl = tvb_get_letohl(tvb, offset);
12940                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
12941                 COUNT_BYTES_TRANS_SUBR(4);
12942
12943                 /* label */
12944                 fn_len = fnl;
12945                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12946                 CHECK_STRING_TRANS_SUBR(fn);
12947                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
12948                         fn);
12949                 COUNT_BYTES_TRANS_SUBR(fn_len);
12950
12951                 break;
12952         case 0x301:     /* MAC_QUERY_FS_INFO */
12953                 /* Create time */
12954                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12955                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12956                 *bcp -= 8;
12957                 /* Modify Time */
12958                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12959                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_modify_time);
12960                 *bcp -= 8;
12961                 /* Backup Time */
12962                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12963                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_backup_time);
12964                 *bcp -= 8;
12965                 /* Allocation blocks */
12966                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12967                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
12968                                     offset,
12969                                     4, TRUE);
12970                 COUNT_BYTES_TRANS_SUBR(4);
12971                 /* Allocation Block Size */
12972                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12973                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
12974                                     offset, 4, TRUE);
12975                 COUNT_BYTES_TRANS_SUBR(4);
12976                 /* Free Block Count */
12977                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12978                 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
12979                                     offset, 4, TRUE);
12980                 COUNT_BYTES_TRANS_SUBR(4);
12981                 /* Finder Info ... */
12982                 CHECK_BYTE_COUNT_TRANS_SUBR(32);
12983                 proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb,
12984                                             offset, 32,
12985                                             tvb_get_ptr(tvb, offset,32),
12986                                             "Finder Info: %s",
12987                                             tvb_format_text(tvb, offset, 32));
12988                 COUNT_BYTES_TRANS_SUBR(32);
12989                 /* Number Files */
12990                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12991                 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
12992                                     offset, 4, TRUE);
12993                 COUNT_BYTES_TRANS_SUBR(4);
12994                 /* Number of Root Directories */
12995                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12996                 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
12997                                     offset, 4, TRUE);
12998                 COUNT_BYTES_TRANS_SUBR(4);
12999                 /* Number of files */
13000                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13001                 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
13002                                     offset, 4, TRUE);
13003                 COUNT_BYTES_TRANS_SUBR(4);
13004                 /* Dir Count */
13005                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13006                 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
13007                                     offset, 4, TRUE);
13008                 COUNT_BYTES_TRANS_SUBR(4);
13009                 /* Mac Support Flags */
13010                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13011                 support = tvb_get_ntohl(tvb, offset);
13012                 item = proto_tree_add_text(tree, tvb, offset, 4,
13013                                            "Mac Support Flags: 0x%08x", support);
13014                 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
13015                 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
13016                                        tvb, offset, 4, support);
13017                 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
13018                                        tvb, offset, 4, support);
13019                 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
13020                                        tvb, offset, 4, support);
13021                 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
13022                                        tvb, offset, 4, support);
13023                 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
13024                                        tvb, offset, 4, support);
13025                 COUNT_BYTES_TRANS_SUBR(4);
13026                 break;
13027         case 1006:      /* QUERY_FS_QUOTA_INFO */
13028                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
13029                 break;
13030         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
13031                 /* allocation size */
13032                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13033                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13034                 COUNT_BYTES_TRANS_SUBR(8);
13035
13036                 /* caller free allocation units */
13037                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13038                 proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
13039                 COUNT_BYTES_TRANS_SUBR(8);
13040
13041                 /* actual free allocation units */
13042                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13043                 proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
13044                 COUNT_BYTES_TRANS_SUBR(8);
13045
13046                 /* sectors per unit */
13047                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13048                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13049                 COUNT_BYTES_TRANS_SUBR(4);
13050
13051                 /* bytes per sector */
13052                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13053                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
13054                 COUNT_BYTES_TRANS_SUBR(4);
13055                 break;
13056         }
13057
13058         return offset;
13059 }
13060
13061 static int
13062 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
13063     proto_tree *parent_tree)
13064 {
13065         proto_item *item = NULL;
13066         proto_tree *tree = NULL;
13067         smb_info_t *si;
13068         smb_transact2_info_t *t2i;
13069         int count;
13070         gboolean trunc;
13071         int offset = 0;
13072         guint16 dc;
13073
13074         dc = tvb_reported_length(tvb);
13075
13076         si = (smb_info_t *)pinfo->private_data;
13077         if (si->sip != NULL)
13078                 t2i = si->sip->extra_info;
13079         else
13080                 t2i = NULL;
13081
13082         if(parent_tree){
13083                 if (t2i != NULL && t2i->subcmd != -1) {
13084                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13085                                 "%s Data",
13086                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
13087                                         "Unknown (0x%02x)"));
13088                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
13089                 } else {
13090                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13091                                 "Unknown Transaction2 Data");
13092                 }
13093         }
13094
13095         if (t2i == NULL) {
13096                 offset += dc;
13097                 return offset;
13098         }
13099         switch(t2i->subcmd){
13100         case 0x00:      /*TRANS2_OPEN2*/
13101                 /* XXX not implemented yet. See SNIA doc */
13102                 break;
13103         case 0x01:      /*TRANS2_FIND_FIRST2*/
13104                 /* returned data */
13105                 count = si->info_count;
13106
13107                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
13108                         col_append_fstr(pinfo->cinfo, COL_INFO,
13109                         ", Files:");
13110                 }
13111
13112                 while(count--){
13113                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
13114                                 offset, &dc, &trunc);
13115                         if (trunc)
13116                                 break;
13117                 }
13118                 break;
13119         case 0x02:      /*TRANS2_FIND_NEXT2*/
13120                 /* returned data */
13121                 count = si->info_count;
13122
13123                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
13124                         col_append_fstr(pinfo->cinfo, COL_INFO,
13125                         ", Files:");
13126                 }
13127
13128                 while(count--){
13129                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
13130                                 offset, &dc, &trunc);
13131                         if (trunc)
13132                                 break;
13133                 }
13134                 break;
13135         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
13136                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
13137                 break;
13138         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
13139                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
13140                 break;
13141         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
13142                 /* no data in this response */
13143                 break;
13144         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
13145                 /* identical to QUERY_PATH_INFO */
13146                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
13147                 break;
13148         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
13149                 /* no data in this response */
13150                 break;
13151         case 0x09:      /*TRANS2_FSCTL*/
13152                 /* XXX dont know how to dissect this one (yet)*/
13153
13154                 /*
13155                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13156                  * Extensions Version 3.0, Document Version 1.11,
13157                  * July 19, 1990" says this this contains a
13158                  * "File system specific return data block".
13159                  * (That means we may not be able to dissect it in any
13160                  * case.)
13161                  */
13162                 break;
13163         case 0x0a:      /*TRANS2_IOCTL2*/
13164                 /* XXX dont know how to dissect this one (yet)*/
13165
13166                 /*
13167                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13168                  * Extensions Version 3.0, Document Version 1.11,
13169                  * July 19, 1990" says this this contains a
13170                  * "Device/function specific return data block".
13171                  * (That means we may not be able to dissect it in any
13172                  * case.)
13173                  */
13174                 break;
13175         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
13176                 /* XXX dont know how to dissect this one (yet)*/
13177
13178                 /*
13179                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13180                  * Extensions Version 3.0, Document Version 1.11,
13181                  * July 19, 1990" says this this contains "the level
13182                  * dependent information about the changes which
13183                  * occurred".
13184                  */
13185                 break;
13186         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
13187                 /* XXX dont know how to dissect this one (yet)*/
13188
13189                 /*
13190                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13191                  * Extensions Version 3.0, Document Version 1.11,
13192                  * July 19, 1990" says this this contains "the level
13193                  * dependent information about the changes which
13194                  * occurred".
13195                  */
13196                 break;
13197         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
13198                 /* no data in this response */
13199                 break;
13200         case 0x0e:      /*TRANS2_SESSION_SETUP*/
13201                 /* XXX dont know how to dissect this one (yet)*/
13202                 break;
13203         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
13204                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
13205                 break;
13206         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13207                 /* the SNIA spec appears to say the response has no data */
13208                 break;
13209         case -1:
13210                 /*
13211                  * We don't know what the matching request was; don't
13212                  * bother putting anything else into the tree for the data.
13213                  */
13214                 offset += dc;
13215                 dc = 0;
13216                 break;
13217         }
13218
13219         /* ooops there were data we didnt know how to process */
13220         if(dc != 0){
13221                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
13222                 offset += dc;
13223         }
13224
13225         return offset;
13226 }
13227
13228
13229 static void
13230 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
13231 {
13232         proto_item *item = NULL;
13233         proto_tree *tree = NULL;
13234         smb_info_t *si;
13235         smb_transact2_info_t *t2i;
13236         guint16 fid;
13237         int lno;
13238         int offset = 0;
13239         int pc;
13240
13241         pc = tvb_reported_length(tvb);
13242
13243         si = (smb_info_t *)pinfo->private_data;
13244         if (si->sip != NULL)
13245                 t2i = si->sip->extra_info;
13246         else
13247                 t2i = NULL;
13248
13249         if(parent_tree){
13250                 if (t2i != NULL && t2i->subcmd != -1) {
13251                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13252                                 "%s Parameters",
13253                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
13254                                                 "Unknown (0x%02x)"));
13255                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
13256                 } else {
13257                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13258                                 "Unknown Transaction2 Parameters");
13259                 }
13260         }
13261
13262         if (t2i == NULL) {
13263                 offset += pc;
13264                 return;
13265         }
13266         switch(t2i->subcmd){
13267         case 0x00:      /*TRANS2_OPEN2*/
13268                 /* fid */
13269                 fid = tvb_get_letohs(tvb, offset);
13270                 add_fid(tvb, pinfo, tree, offset, 2, fid);
13271                 offset += 2;
13272
13273                 /*
13274                  * XXX - Microsoft Networks SMB File Sharing Protocol
13275                  * Extensions Version 3.0, Document Version 1.11,
13276                  * July 19, 1990 says that the file attributes, create
13277                  * time (which it says is the last modification time),
13278                  * data size, granted access, file type, and IPC state
13279                  * are returned only if bit 0 is set in the open flags,
13280                  * and that the EA length is returned only if bit 3
13281                  * is set in the open flags.  Does that mean that,
13282                  * at least in that SMB dialect, those fields are not
13283                  * present in the reply parameters if the bits in
13284                  * question aren't set?
13285                  */
13286
13287                 /* File Attributes */
13288                 offset = dissect_file_attributes(tvb, tree, offset, 2);
13289
13290                 /* create time */
13291                 offset = dissect_smb_datetime(tvb, tree, offset,
13292                         hf_smb_create_time,
13293                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
13294
13295                 /* data size */
13296                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
13297                 offset += 4;
13298
13299                 /* granted access */
13300                 offset = dissect_access(tvb, tree, offset, "Granted");
13301
13302                 /* File Type */
13303                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
13304                 offset += 2;
13305
13306                 /* IPC State */
13307                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
13308
13309                 /* open_action */
13310                 offset = dissect_open_action(tvb, tree, offset);
13311
13312                 /* server unique file ID */
13313                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
13314                 offset += 4;
13315
13316                 /* ea error offset, only a 16 bit integer here */
13317                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13318                 offset += 2;
13319
13320                 /* ea length */
13321                 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13322                 offset += 4;
13323
13324                 break;
13325         case 0x01:      /*TRANS2_FIND_FIRST2*/
13326                 /* Find First2 information level */
13327                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
13328
13329                 /* sid */
13330                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
13331                 offset += 2;
13332
13333                 /* search count */
13334                 si->info_count = tvb_get_letohs(tvb, offset);
13335                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13336                 offset += 2;
13337
13338                 /* end of search */
13339                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13340                 offset += 2;
13341
13342                 /* ea error offset, only a 16 bit integer here */
13343                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13344                 offset += 2;
13345
13346                 /* last name offset */
13347                 lno = tvb_get_letohs(tvb, offset);
13348                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13349                 offset += 2;
13350
13351                 break;
13352         case 0x02:      /*TRANS2_FIND_NEXT2*/
13353                 /* search count */
13354                 si->info_count = tvb_get_letohs(tvb, offset);
13355                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13356                 offset += 2;
13357
13358                 /* end of search */
13359                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13360                 offset += 2;
13361
13362                 /* ea_error_offset, only a 16 bit integer here*/
13363                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13364                 offset += 2;
13365
13366                 /* last name offset */
13367                 lno = tvb_get_letohs(tvb, offset);
13368                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13369                 offset += 2;
13370
13371                 break;
13372         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
13373                 /* no parameter block here */
13374                 break;
13375         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
13376                 /* ea_error_offset, only a 16 bit integer here*/
13377                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13378                 offset += 2;
13379
13380                 break;
13381         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
13382                 /* ea_error_offset, only a 16 bit integer here*/
13383                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13384                 offset += 2;
13385
13386                 break;
13387         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
13388                 /* ea_error_offset, only a 16 bit integer here*/
13389                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13390                 offset += 2;
13391
13392                 break;
13393         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
13394                 /* ea_error_offset, only a 16 bit integer here*/
13395                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13396                 offset += 2;
13397
13398                 break;
13399         case 0x09:      /*TRANS2_FSCTL*/
13400                 /* XXX dont know how to dissect this one (yet)*/
13401
13402                 /*
13403                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13404                  * Extensions Version 3.0, Document Version 1.11,
13405                  * July 19, 1990" says this this contains a
13406                  * "File system specific return parameter block".
13407                  * (That means we may not be able to dissect it in any
13408                  * case.)
13409                  */
13410                 break;
13411         case 0x0a:      /*TRANS2_IOCTL2*/
13412                 /* XXX dont know how to dissect this one (yet)*/
13413
13414                 /*
13415                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13416                  * Extensions Version 3.0, Document Version 1.11,
13417                  * July 19, 1990" says this this contains a
13418                  * "Device/function specific return parameter block".
13419                  * (That means we may not be able to dissect it in any
13420                  * case.)
13421                  */
13422                 break;
13423         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
13424                 /* Find Notify information level */
13425                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13426
13427                 /* Monitor handle */
13428                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
13429                 offset += 2;
13430
13431                 /* Change count */
13432                 si->info_count = tvb_get_letohs(tvb, offset);
13433                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13434                 offset += 2;
13435
13436                 /* ea_error_offset, only a 16 bit integer here*/
13437                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13438                 offset += 2;
13439
13440                 break;
13441         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
13442                 /* Find Notify information level */
13443                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13444
13445                 /* Change count */
13446                 si->info_count = tvb_get_letohs(tvb, offset);
13447                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13448                 offset += 2;
13449
13450                 /* ea_error_offset, only a 16 bit integer here*/
13451                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13452                 offset += 2;
13453
13454                 break;
13455         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
13456                 /* ea error offset, only a 16 bit integer here */
13457                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13458                 offset += 2;
13459
13460                 break;
13461         case 0x0e:      /*TRANS2_SESSION_SETUP*/
13462                 /* XXX dont know how to dissect this one (yet)*/
13463                 break;
13464         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
13465                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
13466                 break;
13467         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13468                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
13469                 break;
13470         case -1:
13471                 /*
13472                  * We don't know what the matching request was; don't
13473                  * bother putting anything else into the tree for the data.
13474                  */
13475                 offset += pc;
13476                 break;
13477         }
13478
13479         /* ooops there were data we didnt know how to process */
13480         if(offset<pc){
13481                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
13482                 offset += pc-offset;
13483         }
13484 }
13485
13486
13487 static int
13488 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13489 {
13490         guint8 sc, wc;
13491         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
13492         smb_info_t *si;
13493         smb_transact2_info_t *t2i = NULL;
13494         guint16 bc;
13495         int padcnt;
13496         gboolean dissected_trans;
13497         fragment_data *r_fd = NULL;
13498         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
13499         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
13500         gboolean save_fragmented;
13501
13502         si = (smb_info_t *)pinfo->private_data;
13503
13504         switch(si->cmd){
13505         case SMB_COM_TRANSACTION2:
13506                 /* transaction2 */
13507                 if (si->sip != NULL) {
13508                         t2i = si->sip->extra_info;
13509                 } else
13510                         t2i = NULL;
13511                 if (t2i == NULL) {
13512                         /*
13513                          * We didn't see the matching request, so we don't
13514                          * know what type of transaction this is.
13515                          */
13516                         proto_tree_add_text(tree, tvb, 0, 0,
13517                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
13518                         if (check_col(pinfo->cinfo, COL_INFO)) {
13519                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
13520                         }
13521                 } else {
13522                         si->info_level = t2i->info_level;
13523                         if (t2i->subcmd == -1) {
13524                                 /*
13525                                  * We didn't manage to extract the subcommand
13526                                  * from the matching request (perhaps because
13527                                  * the frame was short), so we don't know what
13528                                  * type of transaction this is.
13529                                  */
13530                                 proto_tree_add_text(tree, tvb, 0, 0,
13531                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
13532                                 if (check_col(pinfo->cinfo, COL_INFO)) {
13533                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
13534                                 }
13535                         } else {
13536                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
13537                                 if (check_col(pinfo->cinfo, COL_INFO)) {
13538                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13539                                                 val_to_str(t2i->subcmd,
13540                                                         trans2_cmd_vals,
13541                                                         "<unknown (0x%02x)>"));
13542                                 }
13543                         }
13544                 }
13545                 break;
13546         }
13547
13548         WORD_COUNT;
13549
13550         /* total param count, only a 16bit integer here */
13551         tp = tvb_get_letohs(tvb, offset);
13552         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
13553         offset += 2;
13554
13555         /* total data count, only a 16 bit integer here */
13556         td = tvb_get_letohs(tvb, offset);
13557         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
13558         offset += 2;
13559
13560         /* 2 reserved bytes */
13561         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
13562         offset += 2;
13563
13564         /* param count */
13565         pc = tvb_get_letohs(tvb, offset);
13566         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
13567         offset += 2;
13568
13569         /* param offset */
13570         po = tvb_get_letohs(tvb, offset);
13571         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
13572         offset += 2;
13573
13574         /* param disp */
13575         pd = tvb_get_letohs(tvb, offset);
13576         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
13577         offset += 2;
13578
13579         /* data count */
13580         dc = tvb_get_letohs(tvb, offset);
13581         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
13582         offset += 2;
13583
13584         /* data offset */
13585         od = tvb_get_letohs(tvb, offset);
13586         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
13587         offset += 2;
13588
13589         /* data disp */
13590         dd = tvb_get_letohs(tvb, offset);
13591         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
13592         offset += 2;
13593
13594         /* setup count */
13595         sc = tvb_get_guint8(tvb, offset);
13596         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
13597         offset += 1;
13598
13599         /* reserved byte */
13600         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
13601         offset += 1;
13602
13603
13604         /* if there were any setup bytes, put them in a tvb for later */
13605         if(sc){
13606                 if((2*sc)>tvb_length_remaining(tvb, offset)){
13607                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
13608                 } else {
13609                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
13610                 }
13611                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
13612         } else {
13613                 s_tvb = NULL;
13614                 sp_tvb=NULL;
13615         }
13616         offset += 2*sc;
13617
13618
13619         BYTE_COUNT;
13620
13621
13622         /* reassembly of SMB Transaction data payload.
13623            In this section we do reassembly of both the data and parameters
13624            blocks of the SMB transaction command.
13625         */
13626         save_fragmented = pinfo->fragmented;
13627         /* do we need reassembly? */
13628         if( (td!=dc) || (tp!=pc) ){
13629                 /* oh yeah, either data or parameter section needs
13630                    reassembly
13631                 */
13632                 pinfo->fragmented = TRUE;
13633                 if(smb_trans_reassembly){
13634                         /* ...and we were told to do reassembly */
13635                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
13636                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
13637                                                              po, pc, pd, td+tp);
13638
13639                         }
13640                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
13641                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
13642                                                              od, dc, dd+tp, td+tp);
13643                         }
13644                 }
13645         }
13646
13647         /* if we got a reassembled fd structure from the reassembly routine we must
13648            create pd_tvb from it
13649         */
13650         if(r_fd){
13651                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
13652                                              r_fd->datalen);
13653                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
13654                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
13655                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
13656         }
13657
13658
13659         if(pd_tvb){
13660                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
13661                 if(tp){
13662                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
13663                 }
13664                 if(td){
13665                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
13666                 }
13667         } else {
13668                 /* It was not reassembled. Do as best as we can.
13669                  * in this case we always try to dissect the stuff if
13670                  * data and param displacement is 0. i.e. for the first
13671                  * (and maybe only) packet.
13672                  */
13673                 if( (pd==0) && (dd==0) ){
13674                         int min;
13675                         int reported_min;
13676                         min = MIN(pc,tvb_length_remaining(tvb,po));
13677                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
13678                         if(min && reported_min) {
13679                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
13680                         }
13681                         min = MIN(dc,tvb_length_remaining(tvb,od));
13682                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
13683                         if(min && reported_min) {
13684                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
13685                         }
13686                         /*
13687                          * A tvbuff containing the parameters
13688                          * and the data.
13689                          * XXX - check pc and dc as well?
13690                          */
13691                         if (tvb_length_remaining(tvb, po)){
13692                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
13693                         }
13694                 }
13695         }
13696
13697
13698
13699         /* parameters */
13700         if(po>offset){
13701                 /* We have some padding bytes.
13702                 */
13703                 padcnt = po-offset;
13704                 if (padcnt > bc)
13705                         padcnt = bc;
13706                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
13707                 COUNT_BYTES(padcnt);
13708         }
13709         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
13710                 /* TRANSACTION2 parameters*/
13711                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
13712         }
13713         COUNT_BYTES(pc);
13714
13715
13716         /* data */
13717         if(od>offset){
13718                 /* We have some initial padding bytes.
13719                 */
13720                 padcnt = od-offset;
13721                 if (padcnt > bc)
13722                         padcnt = bc;
13723                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
13724                 COUNT_BYTES(padcnt);
13725         }
13726         /*
13727          * If the data count is bigger than the count of bytes
13728          * remaining, clamp it so that the count of bytes remaining
13729          * doesn't go negative.
13730          */
13731         if (dc > bc)
13732                 dc = bc;
13733         COUNT_BYTES(dc);
13734
13735
13736
13737         /* from now on, everything is in separate tvbuffs so we dont count
13738            the bytes with COUNT_BYTES any more.
13739            neither do we reference offset any more (which by now points to the
13740            first byte AFTER this PDU */
13741
13742
13743         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
13744                 /* TRANSACTION2 parameters*/
13745                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
13746         }
13747
13748
13749         if(si->cmd==SMB_COM_TRANSACTION){
13750                 smb_transact_info_t *tri;
13751
13752                 dissected_trans = FALSE;
13753                 if (si->sip != NULL)
13754                         tri = si->sip->extra_info;
13755                 else
13756                         tri = NULL;
13757                 if (tri != NULL) {
13758                         switch(tri->subcmd){
13759
13760                         case TRANSACTION_PIPE:
13761                                 /* This function is safe to call for
13762                                    s_tvb==sp_tvb==NULL, i.e. if we don't
13763                                    know them at this point.
13764                                    It's also safe to call if "p_tvb"
13765                                    or "d_tvb" are null.
13766                                 */
13767                                 if( pd_tvb) {
13768                                         dissected_trans = dissect_pipe_smb(
13769                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
13770                                                 d_tvb, NULL, pinfo, top_tree);
13771                                 }
13772                                 break;
13773
13774                         case TRANSACTION_MAILSLOT:
13775                                 /* This one should be safe to call
13776                                    even if s_tvb and sp_tvb is NULL
13777                                 */
13778                                 if(d_tvb){
13779                                         dissected_trans = dissect_mailslot_smb(
13780                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
13781                                                 top_tree);
13782                                 }
13783                                 break;
13784                         }
13785                 }
13786                 if (!dissected_trans) {
13787                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
13788                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
13789                 }
13790         }
13791
13792
13793         if( (p_tvb==0) && (d_tvb==0) ){
13794                 if(check_col(pinfo->cinfo, COL_INFO)){
13795                         col_append_str(pinfo->cinfo, COL_INFO,
13796                                        "[transact continuation]");
13797                 }
13798         }
13799
13800         pinfo->fragmented = save_fragmented;
13801         END_OF_SMB
13802
13803         return offset;
13804 }
13805
13806
13807 static int
13808 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13809 {
13810         guint8 wc;
13811         guint16 bc;
13812
13813         WORD_COUNT;
13814
13815         /* Monitor handle */
13816         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
13817         offset += 2;
13818
13819         BYTE_COUNT;
13820
13821         END_OF_SMB
13822
13823         return offset;
13824 }
13825
13826 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
13827    END Transaction/Transaction2 Primary and secondary requests
13828    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
13829
13830
13831 static int
13832 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13833 {
13834         guint8 wc;
13835         guint16 bc;
13836
13837         WORD_COUNT;
13838
13839         if (wc != 0) {
13840                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
13841                 offset += wc*2;
13842         }
13843
13844         BYTE_COUNT;
13845
13846         if (bc != 0) {
13847                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
13848                 offset += bc;
13849                 bc = 0;
13850         }
13851
13852         END_OF_SMB
13853
13854         return offset;
13855 }
13856
13857 typedef struct _smb_function {
13858        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13859        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13860 } smb_function;
13861
13862 static smb_function smb_dissector[256] = {
13863   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
13864   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
13865   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
13866   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
13867   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
13868   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
13869   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
13870   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
13871   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
13872   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
13873   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
13874   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
13875   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
13876   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
13877   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
13878   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
13879
13880   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
13881   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
13882   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
13883   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
13884   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
13885   /* 0x15 */  {dissect_unknown, dissect_unknown},
13886   /* 0x16 */  {dissect_unknown, dissect_unknown},
13887   /* 0x17 */  {dissect_unknown, dissect_unknown},
13888   /* 0x18 */  {dissect_unknown, dissect_unknown},
13889   /* 0x19 */  {dissect_unknown, dissect_unknown},
13890   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
13891   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
13892   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
13893   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
13894   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
13895   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
13896
13897   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
13898   /* 0x21 */  {dissect_unknown, dissect_unknown},
13899   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
13900   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
13901   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
13902   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
13903   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
13904   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
13905   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
13906   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
13907   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
13908   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
13909   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
13910   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
13911   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
13912   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
13913
13914   /* 0x30 */  {dissect_unknown, dissect_unknown},
13915   /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
13916   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
13917   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
13918   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
13919   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
13920   /* 0x36 */  {dissect_unknown, dissect_unknown},
13921   /* 0x37 */  {dissect_unknown, dissect_unknown},
13922   /* 0x38 */  {dissect_unknown, dissect_unknown},
13923   /* 0x39 */  {dissect_unknown, dissect_unknown},
13924   /* 0x3a */  {dissect_unknown, dissect_unknown},
13925   /* 0x3b */  {dissect_unknown, dissect_unknown},
13926   /* 0x3c */  {dissect_unknown, dissect_unknown},
13927   /* 0x3d */  {dissect_unknown, dissect_unknown},
13928   /* 0x3e */  {dissect_unknown, dissect_unknown},
13929   /* 0x3f */  {dissect_unknown, dissect_unknown},
13930
13931   /* 0x40 */  {dissect_unknown, dissect_unknown},
13932   /* 0x41 */  {dissect_unknown, dissect_unknown},
13933   /* 0x42 */  {dissect_unknown, dissect_unknown},
13934   /* 0x43 */  {dissect_unknown, dissect_unknown},
13935   /* 0x44 */  {dissect_unknown, dissect_unknown},
13936   /* 0x45 */  {dissect_unknown, dissect_unknown},
13937   /* 0x46 */  {dissect_unknown, dissect_unknown},
13938   /* 0x47 */  {dissect_unknown, dissect_unknown},
13939   /* 0x48 */  {dissect_unknown, dissect_unknown},
13940   /* 0x49 */  {dissect_unknown, dissect_unknown},
13941   /* 0x4a */  {dissect_unknown, dissect_unknown},
13942   /* 0x4b */  {dissect_unknown, dissect_unknown},
13943   /* 0x4c */  {dissect_unknown, dissect_unknown},
13944   /* 0x4d */  {dissect_unknown, dissect_unknown},
13945   /* 0x4e */  {dissect_unknown, dissect_unknown},
13946   /* 0x4f */  {dissect_unknown, dissect_unknown},
13947
13948   /* 0x50 */  {dissect_unknown, dissect_unknown},
13949   /* 0x51 */  {dissect_unknown, dissect_unknown},
13950   /* 0x52 */  {dissect_unknown, dissect_unknown},
13951   /* 0x53 */  {dissect_unknown, dissect_unknown},
13952   /* 0x54 */  {dissect_unknown, dissect_unknown},
13953   /* 0x55 */  {dissect_unknown, dissect_unknown},
13954   /* 0x56 */  {dissect_unknown, dissect_unknown},
13955   /* 0x57 */  {dissect_unknown, dissect_unknown},
13956   /* 0x58 */  {dissect_unknown, dissect_unknown},
13957   /* 0x59 */  {dissect_unknown, dissect_unknown},
13958   /* 0x5a */  {dissect_unknown, dissect_unknown},
13959   /* 0x5b */  {dissect_unknown, dissect_unknown},
13960   /* 0x5c */  {dissect_unknown, dissect_unknown},
13961   /* 0x5d */  {dissect_unknown, dissect_unknown},
13962   /* 0x5e */  {dissect_unknown, dissect_unknown},
13963   /* 0x5f */  {dissect_unknown, dissect_unknown},
13964
13965   /* 0x60 */  {dissect_unknown, dissect_unknown},
13966   /* 0x61 */  {dissect_unknown, dissect_unknown},
13967   /* 0x62 */  {dissect_unknown, dissect_unknown},
13968   /* 0x63 */  {dissect_unknown, dissect_unknown},
13969   /* 0x64 */  {dissect_unknown, dissect_unknown},
13970   /* 0x65 */  {dissect_unknown, dissect_unknown},
13971   /* 0x66 */  {dissect_unknown, dissect_unknown},
13972   /* 0x67 */  {dissect_unknown, dissect_unknown},
13973   /* 0x68 */  {dissect_unknown, dissect_unknown},
13974   /* 0x69 */  {dissect_unknown, dissect_unknown},
13975   /* 0x6a */  {dissect_unknown, dissect_unknown},
13976   /* 0x6b */  {dissect_unknown, dissect_unknown},
13977   /* 0x6c */  {dissect_unknown, dissect_unknown},
13978   /* 0x6d */  {dissect_unknown, dissect_unknown},
13979   /* 0x6e */  {dissect_unknown, dissect_unknown},
13980   /* 0x6f */  {dissect_unknown, dissect_unknown},
13981
13982   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
13983   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
13984   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
13985   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
13986   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
13987   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
13988   /* 0x76 */  {dissect_unknown, dissect_unknown},
13989   /* 0x77 */  {dissect_unknown, dissect_unknown},
13990   /* 0x78 */  {dissect_unknown, dissect_unknown},
13991   /* 0x79 */  {dissect_unknown, dissect_unknown},
13992   /* 0x7a */  {dissect_unknown, dissect_unknown},
13993   /* 0x7b */  {dissect_unknown, dissect_unknown},
13994   /* 0x7c */  {dissect_unknown, dissect_unknown},
13995   /* 0x7d */  {dissect_unknown, dissect_unknown},
13996   /* 0x7e */  {dissect_unknown, dissect_unknown},
13997   /* 0x7f */  {dissect_unknown, dissect_unknown},
13998
13999   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
14000   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
14001   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
14002   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
14003   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
14004   /* 0x85 */  {dissect_unknown, dissect_unknown},
14005   /* 0x86 */  {dissect_unknown, dissect_unknown},
14006   /* 0x87 */  {dissect_unknown, dissect_unknown},
14007   /* 0x88 */  {dissect_unknown, dissect_unknown},
14008   /* 0x89 */  {dissect_unknown, dissect_unknown},
14009   /* 0x8a */  {dissect_unknown, dissect_unknown},
14010   /* 0x8b */  {dissect_unknown, dissect_unknown},
14011   /* 0x8c */  {dissect_unknown, dissect_unknown},
14012   /* 0x8d */  {dissect_unknown, dissect_unknown},
14013   /* 0x8e */  {dissect_unknown, dissect_unknown},
14014   /* 0x8f */  {dissect_unknown, dissect_unknown},
14015
14016   /* 0x90 */  {dissect_unknown, dissect_unknown},
14017   /* 0x91 */  {dissect_unknown, dissect_unknown},
14018   /* 0x92 */  {dissect_unknown, dissect_unknown},
14019   /* 0x93 */  {dissect_unknown, dissect_unknown},
14020   /* 0x94 */  {dissect_unknown, dissect_unknown},
14021   /* 0x95 */  {dissect_unknown, dissect_unknown},
14022   /* 0x96 */  {dissect_unknown, dissect_unknown},
14023   /* 0x97 */  {dissect_unknown, dissect_unknown},
14024   /* 0x98 */  {dissect_unknown, dissect_unknown},
14025   /* 0x99 */  {dissect_unknown, dissect_unknown},
14026   /* 0x9a */  {dissect_unknown, dissect_unknown},
14027   /* 0x9b */  {dissect_unknown, dissect_unknown},
14028   /* 0x9c */  {dissect_unknown, dissect_unknown},
14029   /* 0x9d */  {dissect_unknown, dissect_unknown},
14030   /* 0x9e */  {dissect_unknown, dissect_unknown},
14031   /* 0x9f */  {dissect_unknown, dissect_unknown},
14032
14033   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
14034   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
14035   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
14036   /* 0xa3 */  {dissect_unknown, dissect_unknown},
14037   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
14038   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
14039   /* 0xa6 */  {dissect_unknown, dissect_unknown},
14040   /* 0xa7 */  {dissect_unknown, dissect_unknown},
14041   /* 0xa8 */  {dissect_unknown, dissect_unknown},
14042   /* 0xa9 */  {dissect_unknown, dissect_unknown},
14043   /* 0xaa */  {dissect_unknown, dissect_unknown},
14044   /* 0xab */  {dissect_unknown, dissect_unknown},
14045   /* 0xac */  {dissect_unknown, dissect_unknown},
14046   /* 0xad */  {dissect_unknown, dissect_unknown},
14047   /* 0xae */  {dissect_unknown, dissect_unknown},
14048   /* 0xaf */  {dissect_unknown, dissect_unknown},
14049
14050   /* 0xb0 */  {dissect_unknown, dissect_unknown},
14051   /* 0xb1 */  {dissect_unknown, dissect_unknown},
14052   /* 0xb2 */  {dissect_unknown, dissect_unknown},
14053   /* 0xb3 */  {dissect_unknown, dissect_unknown},
14054   /* 0xb4 */  {dissect_unknown, dissect_unknown},
14055   /* 0xb5 */  {dissect_unknown, dissect_unknown},
14056   /* 0xb6 */  {dissect_unknown, dissect_unknown},
14057   /* 0xb7 */  {dissect_unknown, dissect_unknown},
14058   /* 0xb8 */  {dissect_unknown, dissect_unknown},
14059   /* 0xb9 */  {dissect_unknown, dissect_unknown},
14060   /* 0xba */  {dissect_unknown, dissect_unknown},
14061   /* 0xbb */  {dissect_unknown, dissect_unknown},
14062   /* 0xbc */  {dissect_unknown, dissect_unknown},
14063   /* 0xbd */  {dissect_unknown, dissect_unknown},
14064   /* 0xbe */  {dissect_unknown, dissect_unknown},
14065   /* 0xbf */  {dissect_unknown, dissect_unknown},
14066
14067   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
14068   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
14069   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
14070   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
14071   /* 0xc4 */  {dissect_unknown, dissect_unknown},
14072   /* 0xc5 */  {dissect_unknown, dissect_unknown},
14073   /* 0xc6 */  {dissect_unknown, dissect_unknown},
14074   /* 0xc7 */  {dissect_unknown, dissect_unknown},
14075   /* 0xc8 */  {dissect_unknown, dissect_unknown},
14076   /* 0xc9 */  {dissect_unknown, dissect_unknown},
14077   /* 0xca */  {dissect_unknown, dissect_unknown},
14078   /* 0xcb */  {dissect_unknown, dissect_unknown},
14079   /* 0xcc */  {dissect_unknown, dissect_unknown},
14080   /* 0xcd */  {dissect_unknown, dissect_unknown},
14081   /* 0xce */  {dissect_unknown, dissect_unknown},
14082   /* 0xcf */  {dissect_unknown, dissect_unknown},
14083
14084   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
14085   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
14086   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
14087   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
14088   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
14089   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
14090   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
14091   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
14092   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
14093   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
14094   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
14095   /* 0xdb */  {dissect_unknown, dissect_unknown},
14096   /* 0xdc */  {dissect_unknown, dissect_unknown},
14097   /* 0xdd */  {dissect_unknown, dissect_unknown},
14098   /* 0xde */  {dissect_unknown, dissect_unknown},
14099   /* 0xdf */  {dissect_unknown, dissect_unknown},
14100
14101   /* 0xe0 */  {dissect_unknown, dissect_unknown},
14102   /* 0xe1 */  {dissect_unknown, dissect_unknown},
14103   /* 0xe2 */  {dissect_unknown, dissect_unknown},
14104   /* 0xe3 */  {dissect_unknown, dissect_unknown},
14105   /* 0xe4 */  {dissect_unknown, dissect_unknown},
14106   /* 0xe5 */  {dissect_unknown, dissect_unknown},
14107   /* 0xe6 */  {dissect_unknown, dissect_unknown},
14108   /* 0xe7 */  {dissect_unknown, dissect_unknown},
14109   /* 0xe8 */  {dissect_unknown, dissect_unknown},
14110   /* 0xe9 */  {dissect_unknown, dissect_unknown},
14111   /* 0xea */  {dissect_unknown, dissect_unknown},
14112   /* 0xeb */  {dissect_unknown, dissect_unknown},
14113   /* 0xec */  {dissect_unknown, dissect_unknown},
14114   /* 0xed */  {dissect_unknown, dissect_unknown},
14115   /* 0xee */  {dissect_unknown, dissect_unknown},
14116   /* 0xef */  {dissect_unknown, dissect_unknown},
14117
14118   /* 0xf0 */  {dissect_unknown, dissect_unknown},
14119   /* 0xf1 */  {dissect_unknown, dissect_unknown},
14120   /* 0xf2 */  {dissect_unknown, dissect_unknown},
14121   /* 0xf3 */  {dissect_unknown, dissect_unknown},
14122   /* 0xf4 */  {dissect_unknown, dissect_unknown},
14123   /* 0xf5 */  {dissect_unknown, dissect_unknown},
14124   /* 0xf6 */  {dissect_unknown, dissect_unknown},
14125   /* 0xf7 */  {dissect_unknown, dissect_unknown},
14126   /* 0xf8 */  {dissect_unknown, dissect_unknown},
14127   /* 0xf9 */  {dissect_unknown, dissect_unknown},
14128   /* 0xfa */  {dissect_unknown, dissect_unknown},
14129   /* 0xfb */  {dissect_unknown, dissect_unknown},
14130   /* 0xfc */  {dissect_unknown, dissect_unknown},
14131   /* 0xfd */  {dissect_unknown, dissect_unknown},
14132   /* 0xfe */  {dissect_unknown, dissect_unknown},
14133   /* 0xff */  {dissect_unknown, dissect_unknown},
14134 };
14135
14136 static int
14137 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
14138 {
14139         smb_info_t *si;
14140
14141         si = pinfo->private_data;
14142         if(cmd!=0xff){
14143                 proto_item *cmd_item;
14144                 proto_tree *cmd_tree;
14145                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14146
14147                 if (check_col(pinfo->cinfo, COL_INFO)) {
14148                         if(first_pdu){
14149                                 col_append_fstr(pinfo->cinfo, COL_INFO,
14150                                         "%s %s",
14151                                         decode_smb_name(cmd),
14152                                         (si->request)? "Request" : "Response");
14153                         } else {
14154                                 col_append_fstr(pinfo->cinfo, COL_INFO,
14155                                         "; %s",
14156                                         decode_smb_name(cmd));
14157                         }
14158
14159                 }
14160
14161                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
14162                         "%s %s (0x%02x)",
14163                         decode_smb_name(cmd),
14164                         (si->request)?"Request":"Response",
14165                         cmd);
14166
14167                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
14168
14169                 dissector = (si->request)?
14170                         smb_dissector[cmd].request:smb_dissector[cmd].response;
14171
14172                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
14173                 proto_item_set_end(cmd_item, tvb, offset);
14174         }
14175         return offset;
14176 }
14177
14178
14179 /* NOTE: this value_string array will also be used to access data directly by
14180  * index instead of val_to_str() since
14181  * 1, the array will always span every value from 0x00 to 0xff and
14182  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
14183  * This means that this value_string array MUST always
14184  * 1, contain all entries 0x00 to 0xff
14185  * 2, all entries must be in order.
14186  */
14187 const value_string smb_cmd_vals[] = {
14188   { 0x00, "Create Directory" },
14189   { 0x01, "Delete Directory" },
14190   { 0x02, "Open" },
14191   { 0x03, "Create" },
14192   { 0x04, "Close" },
14193   { 0x05, "Flush" },
14194   { 0x06, "Delete" },
14195   { 0x07, "Rename" },
14196   { 0x08, "Query Information" },
14197   { 0x09, "Set Information" },
14198   { 0x0A, "Read" },
14199   { 0x0B, "Write" },
14200   { 0x0C, "Lock Byte Range" },
14201   { 0x0D, "Unlock Byte Range" },
14202   { 0x0E, "Create Temp" },
14203   { 0x0F, "Create New" },
14204   { 0x10, "Check Directory" },
14205   { 0x11, "Process Exit" },
14206   { 0x12, "Seek" },
14207   { 0x13, "Lock And Read" },
14208   { 0x14, "Write And Unlock" },
14209   { 0x15, "unknown-0x15" },
14210   { 0x16, "unknown-0x16" },
14211   { 0x17, "unknown-0x17" },
14212   { 0x18, "unknown-0x18" },
14213   { 0x19, "unknown-0x19" },
14214   { 0x1A, "Read Raw" },
14215   { 0x1B, "Read MPX" },
14216   { 0x1C, "Read MPX Secondary" },
14217   { 0x1D, "Write Raw" },
14218   { 0x1E, "Write MPX" },
14219   { 0x1F, "Write MPX Secondary" },
14220   { 0x20, "Write Complete" },
14221   { 0x21, "unknown-0x21" },
14222   { 0x22, "Set Information2" },
14223   { 0x23, "Query Information2" },
14224   { 0x24, "Locking AndX" },
14225   { 0x25, "Transaction" },
14226   { 0x26, "Transaction Secondary" },
14227   { 0x27, "IOCTL" },
14228   { 0x28, "IOCTL Secondary" },
14229   { 0x29, "Copy" },
14230   { 0x2A, "Move" },
14231   { 0x2B, "Echo" },
14232   { 0x2C, "Write And Close" },
14233   { 0x2D, "Open AndX" },
14234   { 0x2E, "Read AndX" },
14235   { 0x2F, "Write AndX" },
14236   { 0x30, "unknown-0x30" },
14237   { 0x31, "Close And Tree Disconnect" },
14238   { 0x32, "Transaction2" },
14239   { 0x33, "Transaction2 Secondary" },
14240   { 0x34, "Find Close2" },
14241   { 0x35, "Find Notify Close" },
14242   { 0x36, "unknown-0x36" },
14243   { 0x37, "unknown-0x37" },
14244   { 0x38, "unknown-0x38" },
14245   { 0x39, "unknown-0x39" },
14246   { 0x3A, "unknown-0x3A" },
14247   { 0x3B, "unknown-0x3B" },
14248   { 0x3C, "unknown-0x3C" },
14249   { 0x3D, "unknown-0x3D" },
14250   { 0x3E, "unknown-0x3E" },
14251   { 0x3F, "unknown-0x3F" },
14252   { 0x40, "unknown-0x40" },
14253   { 0x41, "unknown-0x41" },
14254   { 0x42, "unknown-0x42" },
14255   { 0x43, "unknown-0x43" },
14256   { 0x44, "unknown-0x44" },
14257   { 0x45, "unknown-0x45" },
14258   { 0x46, "unknown-0x46" },
14259   { 0x47, "unknown-0x47" },
14260   { 0x48, "unknown-0x48" },
14261   { 0x49, "unknown-0x49" },
14262   { 0x4A, "unknown-0x4A" },
14263   { 0x4B, "unknown-0x4B" },
14264   { 0x4C, "unknown-0x4C" },
14265   { 0x4D, "unknown-0x4D" },
14266   { 0x4E, "unknown-0x4E" },
14267   { 0x4F, "unknown-0x4F" },
14268   { 0x50, "unknown-0x50" },
14269   { 0x51, "unknown-0x51" },
14270   { 0x52, "unknown-0x52" },
14271   { 0x53, "unknown-0x53" },
14272   { 0x54, "unknown-0x54" },
14273   { 0x55, "unknown-0x55" },
14274   { 0x56, "unknown-0x56" },
14275   { 0x57, "unknown-0x57" },
14276   { 0x58, "unknown-0x58" },
14277   { 0x59, "unknown-0x59" },
14278   { 0x5A, "unknown-0x5A" },
14279   { 0x5B, "unknown-0x5B" },
14280   { 0x5C, "unknown-0x5C" },
14281   { 0x5D, "unknown-0x5D" },
14282   { 0x5E, "unknown-0x5E" },
14283   { 0x5F, "unknown-0x5F" },
14284   { 0x60, "unknown-0x60" },
14285   { 0x61, "unknown-0x61" },
14286   { 0x62, "unknown-0x62" },
14287   { 0x63, "unknown-0x63" },
14288   { 0x64, "unknown-0x64" },
14289   { 0x65, "unknown-0x65" },
14290   { 0x66, "unknown-0x66" },
14291   { 0x67, "unknown-0x67" },
14292   { 0x68, "unknown-0x68" },
14293   { 0x69, "unknown-0x69" },
14294   { 0x6A, "unknown-0x6A" },
14295   { 0x6B, "unknown-0x6B" },
14296   { 0x6C, "unknown-0x6C" },
14297   { 0x6D, "unknown-0x6D" },
14298   { 0x6E, "unknown-0x6E" },
14299   { 0x6F, "unknown-0x6F" },
14300   { 0x70, "Tree Connect" },
14301   { 0x71, "Tree Disconnect" },
14302   { 0x72, "Negotiate Protocol" },
14303   { 0x73, "Session Setup AndX" },
14304   { 0x74, "Logoff AndX" },
14305   { 0x75, "Tree Connect AndX" },
14306   { 0x76, "unknown-0x76" },
14307   { 0x77, "unknown-0x77" },
14308   { 0x78, "unknown-0x78" },
14309   { 0x79, "unknown-0x79" },
14310   { 0x7A, "unknown-0x7A" },
14311   { 0x7B, "unknown-0x7B" },
14312   { 0x7C, "unknown-0x7C" },
14313   { 0x7D, "unknown-0x7D" },
14314   { 0x7E, "unknown-0x7E" },
14315   { 0x7F, "unknown-0x7F" },
14316   { 0x80, "Query Information Disk" },
14317   { 0x81, "Search" },
14318   { 0x82, "Find" },
14319   { 0x83, "Find Unique" },
14320   { 0x84, "Find Close" },
14321   { 0x85, "unknown-0x85" },
14322   { 0x86, "unknown-0x86" },
14323   { 0x87, "unknown-0x87" },
14324   { 0x88, "unknown-0x88" },
14325   { 0x89, "unknown-0x89" },
14326   { 0x8A, "unknown-0x8A" },
14327   { 0x8B, "unknown-0x8B" },
14328   { 0x8C, "unknown-0x8C" },
14329   { 0x8D, "unknown-0x8D" },
14330   { 0x8E, "unknown-0x8E" },
14331   { 0x8F, "unknown-0x8F" },
14332   { 0x90, "unknown-0x90" },
14333   { 0x91, "unknown-0x91" },
14334   { 0x92, "unknown-0x92" },
14335   { 0x93, "unknown-0x93" },
14336   { 0x94, "unknown-0x94" },
14337   { 0x95, "unknown-0x95" },
14338   { 0x96, "unknown-0x96" },
14339   { 0x97, "unknown-0x97" },
14340   { 0x98, "unknown-0x98" },
14341   { 0x99, "unknown-0x99" },
14342   { 0x9A, "unknown-0x9A" },
14343   { 0x9B, "unknown-0x9B" },
14344   { 0x9C, "unknown-0x9C" },
14345   { 0x9D, "unknown-0x9D" },
14346   { 0x9E, "unknown-0x9E" },
14347   { 0x9F, "unknown-0x9F" },
14348   { 0xA0, "NT Transact" },
14349   { 0xA1, "NT Transact Secondary" },
14350   { 0xA2, "NT Create AndX" },
14351   { 0xA3, "unknown-0xA3" },
14352   { 0xA4, "NT Cancel" },
14353   { 0xA5, "NT Rename" },
14354   { 0xA6, "unknown-0xA6" },
14355   { 0xA7, "unknown-0xA7" },
14356   { 0xA8, "unknown-0xA8" },
14357   { 0xA9, "unknown-0xA9" },
14358   { 0xAA, "unknown-0xAA" },
14359   { 0xAB, "unknown-0xAB" },
14360   { 0xAC, "unknown-0xAC" },
14361   { 0xAD, "unknown-0xAD" },
14362   { 0xAE, "unknown-0xAE" },
14363   { 0xAF, "unknown-0xAF" },
14364   { 0xB0, "unknown-0xB0" },
14365   { 0xB1, "unknown-0xB1" },
14366   { 0xB2, "unknown-0xB2" },
14367   { 0xB3, "unknown-0xB3" },
14368   { 0xB4, "unknown-0xB4" },
14369   { 0xB5, "unknown-0xB5" },
14370   { 0xB6, "unknown-0xB6" },
14371   { 0xB7, "unknown-0xB7" },
14372   { 0xB8, "unknown-0xB8" },
14373   { 0xB9, "unknown-0xB9" },
14374   { 0xBA, "unknown-0xBA" },
14375   { 0xBB, "unknown-0xBB" },
14376   { 0xBC, "unknown-0xBC" },
14377   { 0xBD, "unknown-0xBD" },
14378   { 0xBE, "unknown-0xBE" },
14379   { 0xBF, "unknown-0xBF" },
14380   { 0xC0, "Open Print File" },
14381   { 0xC1, "Write Print File" },
14382   { 0xC2, "Close Print File" },
14383   { 0xC3, "Get Print Queue" },
14384   { 0xC4, "unknown-0xC4" },
14385   { 0xC5, "unknown-0xC5" },
14386   { 0xC6, "unknown-0xC6" },
14387   { 0xC7, "unknown-0xC7" },
14388   { 0xC8, "unknown-0xC8" },
14389   { 0xC9, "unknown-0xC9" },
14390   { 0xCA, "unknown-0xCA" },
14391   { 0xCB, "unknown-0xCB" },
14392   { 0xCC, "unknown-0xCC" },
14393   { 0xCD, "unknown-0xCD" },
14394   { 0xCE, "unknown-0xCE" },
14395   { 0xCF, "unknown-0xCF" },
14396   { 0xD0, "Send Single Block Message" },
14397   { 0xD1, "Send Broadcast Message" },
14398   { 0xD2, "Forward User Name" },
14399   { 0xD3, "Cancel Forward" },
14400   { 0xD4, "Get Machine Name" },
14401   { 0xD5, "Send Start of Multi-block Message" },
14402   { 0xD6, "Send End of Multi-block Message" },
14403   { 0xD7, "Send Text of Multi-block Message" },
14404   { 0xD8, "SMBreadbulk" },
14405   { 0xD9, "SMBwritebulk" },
14406   { 0xDA, "SMBwritebulkdata" },
14407   { 0xDB, "unknown-0xDB" },
14408   { 0xDC, "unknown-0xDC" },
14409   { 0xDD, "unknown-0xDD" },
14410   { 0xDE, "unknown-0xDE" },
14411   { 0xDF, "unknown-0xDF" },
14412   { 0xE0, "unknown-0xE0" },
14413   { 0xE1, "unknown-0xE1" },
14414   { 0xE2, "unknown-0xE2" },
14415   { 0xE3, "unknown-0xE3" },
14416   { 0xE4, "unknown-0xE4" },
14417   { 0xE5, "unknown-0xE5" },
14418   { 0xE6, "unknown-0xE6" },
14419   { 0xE7, "unknown-0xE7" },
14420   { 0xE8, "unknown-0xE8" },
14421   { 0xE9, "unknown-0xE9" },
14422   { 0xEA, "unknown-0xEA" },
14423   { 0xEB, "unknown-0xEB" },
14424   { 0xEC, "unknown-0xEC" },
14425   { 0xED, "unknown-0xED" },
14426   { 0xEE, "unknown-0xEE" },
14427   { 0xEF, "unknown-0xEF" },
14428   { 0xF0, "unknown-0xF0" },
14429   { 0xF1, "unknown-0xF1" },
14430   { 0xF2, "unknown-0xF2" },
14431   { 0xF3, "unknown-0xF3" },
14432   { 0xF4, "unknown-0xF4" },
14433   { 0xF5, "unknown-0xF5" },
14434   { 0xF6, "unknown-0xF6" },
14435   { 0xF7, "unknown-0xF7" },
14436   { 0xF8, "unknown-0xF8" },
14437   { 0xF9, "unknown-0xF9" },
14438   { 0xFA, "unknown-0xFA" },
14439   { 0xFB, "unknown-0xFB" },
14440   { 0xFC, "unknown-0xFC" },
14441   { 0xFD, "unknown-0xFD" },
14442   { 0xFE, "SMBinvalid" },
14443   { 0xFF, "unknown-0xFF" },
14444   { 0x00, NULL },
14445 };
14446
14447 static char *decode_smb_name(unsigned char cmd)
14448 {
14449   return(smb_cmd_vals[cmd].strptr);
14450 }
14451
14452
14453
14454 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14455  * Everything TVBUFFIFIED above this line
14456  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
14457
14458
14459 static void
14460 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
14461 {
14462         conv_tables_t *ct = ctarg;
14463
14464         if (ct->unmatched)
14465                 g_hash_table_destroy(ct->unmatched);
14466         if (ct->matched)
14467                 g_hash_table_destroy(ct->matched);
14468         if (ct->tid_service)
14469                 g_hash_table_destroy(ct->tid_service);
14470 }
14471
14472 static void
14473 smb_init_protocol(void)
14474 {
14475         if (smb_saved_info_key_chunk)
14476                 g_mem_chunk_destroy(smb_saved_info_key_chunk);
14477         if (smb_saved_info_chunk)
14478                 g_mem_chunk_destroy(smb_saved_info_chunk);
14479         if (smb_nt_transact_info_chunk)
14480                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
14481         if (smb_transact2_info_chunk)
14482                 g_mem_chunk_destroy(smb_transact2_info_chunk);
14483         if (smb_transact_info_chunk)
14484                 g_mem_chunk_destroy(smb_transact_info_chunk);
14485
14486         /*
14487          * Free the hash tables attached to the conversation table
14488          * structures, and then free the list of conversation table
14489          * data structures (which doesn't free the data structures
14490          * themselves; that's done by destroying the chunk from
14491          * which they were allocated).
14492          */
14493         if (conv_tables) {
14494                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
14495                 g_slist_free(conv_tables);
14496                 conv_tables = NULL;
14497         }
14498
14499         /*
14500          * Now destroy the chunk from which the conversation table
14501          * structures were allocated.
14502          */
14503         if (conv_tables_chunk)
14504                 g_mem_chunk_destroy(conv_tables_chunk);
14505
14506         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
14507             sizeof(smb_saved_info_t),
14508             smb_saved_info_init_count * sizeof(smb_saved_info_t),
14509             G_ALLOC_ONLY);
14510         smb_saved_info_key_chunk = g_mem_chunk_new("smb_saved_info_key_chunk",
14511             sizeof(smb_saved_info_key_t),
14512             smb_saved_info_init_count * sizeof(smb_saved_info_key_t),
14513             G_ALLOC_ONLY);
14514         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
14515             sizeof(smb_nt_transact_info_t),
14516             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
14517             G_ALLOC_ONLY);
14518         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
14519             sizeof(smb_transact2_info_t),
14520             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
14521             G_ALLOC_ONLY);
14522         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
14523             sizeof(smb_transact_info_t),
14524             smb_transact_info_init_count * sizeof(smb_transact_info_t),
14525             G_ALLOC_ONLY);
14526         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
14527             sizeof(conv_tables_t),
14528             conv_tables_count * sizeof(conv_tables_t),
14529             G_ALLOC_ONLY);
14530 }
14531
14532 static const value_string errcls_types[] = {
14533   { SMB_SUCCESS, "Success"},
14534   { SMB_ERRDOS, "DOS Error"},
14535   { SMB_ERRSRV, "Server Error"},
14536   { SMB_ERRHRD, "Hardware Error"},
14537   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
14538   { 0, NULL }
14539 };
14540
14541 const value_string DOS_errors[] = {
14542   {0, "Success"},
14543   {SMBE_insufficientbuffer, "Insufficient buffer"},
14544   {SMBE_badfunc, "Invalid function (or system call)"},
14545   {SMBE_badfile, "File not found (pathname error)"},
14546   {SMBE_badpath, "Directory not found"},
14547   {SMBE_nofids, "Too many open files"},
14548   {SMBE_noaccess, "Access denied"},
14549   {SMBE_badfid, "Invalid fid"},
14550   {SMBE_nomem,  "Out of memory"},
14551   {SMBE_badmem, "Invalid memory block address"},
14552   {SMBE_badenv, "Invalid environment"},
14553   {SMBE_badaccess, "Invalid open mode"},
14554   {SMBE_baddata, "Invalid data (only from ioctl call)"},
14555   {SMBE_res, "Reserved error code?"},
14556   {SMBE_baddrive, "Invalid drive"},
14557   {SMBE_remcd, "Attempt to delete current directory"},
14558   {SMBE_diffdevice, "Rename/move across different filesystems"},
14559   {SMBE_nofiles, "No more files found in file search"},
14560   {SMBE_badshare, "Share mode on file conflict with open mode"},
14561   {SMBE_lock, "Lock request conflicts with existing lock"},
14562   {SMBE_unsup, "Request unsupported, returned by Win 95"},
14563   {SMBE_nosuchshare, "Requested share does not exist"},
14564   {SMBE_filexists, "File in operation already exists"},
14565   {SMBE_cannotopen, "Cannot open the file specified"},
14566   {SMBE_unknownlevel, "Unknown info level"},
14567   {SMBE_invalidname, "Invalid name"},
14568   {SMBE_badpipe, "Named pipe invalid"},
14569   {SMBE_pipebusy, "All instances of pipe are busy"},
14570   {SMBE_pipeclosing, "Named pipe close in progress"},
14571   {SMBE_notconnected, "No process on other end of named pipe"},
14572   {SMBE_moredata, "More data to be returned"},
14573   {SMBE_baddirectory,  "Invalid directory name in a path."},
14574   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
14575   {SMBE_eas_nsup, "Extended attributes not supported"},
14576   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
14577   {SMBE_unknownipc, "Unknown IPC Operation"},
14578   {SMBE_noipc, "Don't support ipc"},
14579   {SMBE_alreadyexists, "File already exists"},
14580   {SMBE_unknownprinterdriver, "Unknown printer driver"},
14581   {SMBE_invalidprintername, "Invalid printer name"},
14582   {SMBE_printeralreadyexists, "Printer already exists"},
14583   {SMBE_invaliddatatype, "Invalid data type"},
14584   {SMBE_invalidenvironment, "Invalid environment"},
14585   {SMBE_printerdriverinuse, "Printer driver in use"},
14586   {SMBE_invalidparam, "Invalid parameter"},
14587   {SMBE_invalidformsize, "Invalid form size"},
14588   {SMBE_invalidsecuritydescriptor, "Invalid security descriptor"},
14589   {SMBE_invalidowner, "Invalid owner"},
14590   {SMBE_nomoreitems, "No more items"},
14591   {SMBE_serverunavailable, "Server unavailable"},
14592   {0, NULL}
14593   };
14594
14595 /* Error codes for the ERRSRV class */
14596
14597 static const value_string SRV_errors[] = {
14598   {SMBE_error, "Non specific error code"},
14599   {SMBE_badpw, "Bad password"},
14600   {SMBE_badtype, "Reserved"},
14601   {SMBE_access, "No permissions to perform the requested operation"},
14602   {SMBE_invnid, "TID invalid"},
14603   {SMBE_invnetname, "Invalid network name. Service not found"},
14604   {SMBE_invdevice, "Invalid device"},
14605   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
14606   {SMBE_qfull, "Print queue full"},
14607   {SMBE_qtoobig, "Queued item too big"},
14608   {SMBE_qeof, "EOF on print queue dump"},
14609   {SMBE_invpfid, "Invalid print file in smb_fid"},
14610   {SMBE_smbcmd, "Unrecognised command"},
14611   {SMBE_srverror, "SMB server internal error"},
14612   {SMBE_filespecs, "Fid and pathname invalid combination"},
14613   {SMBE_badlink, "Bad link in request ???"},
14614   {SMBE_badpermits, "Access specified for a file is not valid"},
14615   {SMBE_badpid, "Bad process id in request"},
14616   {SMBE_setattrmode, "Attribute mode invalid"},
14617   {SMBE_paused, "Message server paused"},
14618   {SMBE_msgoff, "Not receiving messages"},
14619   {SMBE_noroom, "No room for message"},
14620   {SMBE_rmuns, "Too many remote usernames"},
14621   {SMBE_timeout, "Operation timed out"},
14622   {SMBE_noresource, "No resources currently available for request."},
14623   {SMBE_toomanyuids, "Too many userids"},
14624   {SMBE_baduid, "Bad userid"},
14625   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
14626   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
14627   {SMBE_contMPX, "Resume MPX mode"},
14628   {SMBE_badPW, "Bad Password???"},
14629   {SMBE_nosupport, "Operation not supported"},
14630   { 0, NULL}
14631 };
14632
14633 /* Error codes for the ERRHRD class */
14634
14635 static const value_string HRD_errors[] = {
14636   {SMBE_nowrite, "Read only media"},
14637   {SMBE_badunit, "Unknown device"},
14638   {SMBE_notready, "Drive not ready"},
14639   {SMBE_badcmd, "Unknown command"},
14640   {SMBE_data, "Data (CRC) error"},
14641   {SMBE_badreq, "Bad request structure length"},
14642   {SMBE_seek, "Seek error"},
14643   {SMBE_badmedia, "Unknown media type"},
14644   {SMBE_badsector, "Sector not found"},
14645   {SMBE_nopaper, "Printer out of paper"},
14646   {SMBE_write, "Write fault"},
14647   {SMBE_read, "Read fault"},
14648   {SMBE_general, "General failure"},
14649   {SMBE_badshare, "A open conflicts with an existing open"},
14650   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
14651   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
14652   {SMBE_FCBunavail, "No FCBs are available to process request"},
14653   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
14654   {SMBE_diskfull, "Disk full???"},
14655   {0, NULL}
14656 };
14657
14658 static char *decode_smb_error(guint8 errcls, guint16 errcode)
14659 {
14660
14661   switch (errcls) {
14662
14663   case SMB_SUCCESS:
14664
14665     return("No Error");   /* No error ??? */
14666     break;
14667
14668   case SMB_ERRDOS:
14669
14670     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
14671     break;
14672
14673   case SMB_ERRSRV:
14674
14675     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
14676     break;
14677
14678   case SMB_ERRHRD:
14679
14680     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
14681     break;
14682
14683   default:
14684
14685     return("Unknown error class!");
14686
14687   }
14688
14689 }
14690
14691
14692 /* These are the MS country codes from
14693
14694         http://www.unicode.org/unicode/onlinedat/countries.html
14695
14696    For countries that share the same number, I choose to use only the
14697    name of the largest country. Apologies for this. If this offends you,
14698    here is the table to change that.
14699
14700    This also includes the code of 0 for "Default", which isn't in
14701    that list, but is in Microsoft's SDKs and the Cygnus "winnls.h"
14702    header file.  Presumably it means "don't override the setting
14703    on the user's machine".
14704
14705    Future versions of Microsoft's "winnls.h" header file might include
14706    additional codes; the current version matches the Unicode Consortium's
14707    table.
14708 */
14709 const value_string ms_country_codes[] = {
14710         {  0,   "Default"},
14711         {  1,   "USA"},
14712         {  2,   "Canada"},
14713         {  7,   "Russia"},
14714         { 20,   "Egypt"},
14715         { 27,   "South Africa"},
14716         { 30,   "Greece"},
14717         { 31,   "Netherlands"},
14718         { 32,   "Belgium"},
14719         { 33,   "France"},
14720         { 34,   "Spain"},
14721         { 36,   "Hungary"},
14722         { 39,   "Italy"},
14723         { 40,   "Romania"},
14724         { 41,   "Switzerland"},
14725         { 43,   "Austria"},
14726         { 44,   "United Kingdom"},
14727         { 45,   "Denmark"},
14728         { 46,   "Sweden"},
14729         { 47,   "Norway"},
14730         { 48,   "Poland"},
14731         { 49,   "Germany"},
14732         { 51,   "Peru"},
14733         { 52,   "Mexico"},
14734         { 54,   "Argentina"},
14735         { 55,   "Brazil"},
14736         { 56,   "Chile"},
14737         { 57,   "Colombia"},
14738         { 58,   "Venezuela"},
14739         { 60,   "Malaysia"},
14740         { 61,   "Australia"},
14741         { 62,   "Indonesia"},
14742         { 63,   "Philippines"},
14743         { 64,   "New Zealand"},
14744         { 65,   "Singapore"},
14745         { 66,   "Thailand"},
14746         { 81,   "Japan"},
14747         { 82,   "South Korea"},
14748         { 84,   "Viet Nam"},
14749         { 86,   "China"},
14750         { 90,   "Turkey"},
14751         { 91,   "India"},
14752         { 92,   "Pakistan"},
14753         {212,   "Morocco"},
14754         {213,   "Algeria"},
14755         {216,   "Tunisia"},
14756         {218,   "Libya"},
14757         {254,   "Kenya"},
14758         {263,   "Zimbabwe"},
14759         {298,   "Faroe Islands"},
14760         {351,   "Portugal"},
14761         {352,   "Luxembourg"},
14762         {353,   "Ireland"},
14763         {354,   "Iceland"},
14764         {355,   "Albania"},
14765         {358,   "Finland"},
14766         {359,   "Bulgaria"},
14767         {370,   "Lithuania"},
14768         {371,   "Latvia"},
14769         {372,   "Estonia"},
14770         {374,   "Armenia"},
14771         {375,   "Belarus"},
14772         {380,   "Ukraine"},
14773         {381,   "Serbia"},
14774         {385,   "Croatia"},
14775         {386,   "Slovenia"},
14776         {389,   "Macedonia"},
14777         {420,   "Czech Republic"},
14778         {421,   "Slovak Republic"},
14779         {501,   "Belize"},
14780         {502,   "Guatemala"},
14781         {503,   "El Salvador"},
14782         {504,   "Honduras"},
14783         {505,   "Nicaragua"},
14784         {506,   "Costa Rica"},
14785         {507,   "Panama"},
14786         {591,   "Bolivia"},
14787         {593,   "Ecuador"},
14788         {595,   "Paraguay"},
14789         {598,   "Uruguay"},
14790         {673,   "Brunei Darussalam"},
14791         {852,   "Hong Kong"},
14792         {853,   "Macau"},
14793         {886,   "Taiwan"},
14794         {960,   "Maldives"},
14795         {961,   "Lebanon"},
14796         {962,   "Jordan"},
14797         {963,   "Syria"},
14798         {964,   "Iraq"},
14799         {965,   "Kuwait"},
14800         {966,   "Saudi Arabia"},
14801         {967,   "Yemen"},
14802         {968,   "Oman"},
14803         {971,   "United Arab Emirates"},
14804         {972,   "Israel"},
14805         {973,   "Bahrain"},
14806         {974,   "Qatar"},
14807         {976,   "Mongolia"},
14808         {981,   "Iran"},
14809         {994,   "Azerbaijan"},
14810         {995,   "Georgia"},
14811         {996,   "Kyrgyzstan"},
14812
14813         {0,     NULL}
14814 };
14815
14816 /*
14817  * NT error codes.
14818  *
14819  * From
14820  *
14821  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
14822  */
14823 const value_string NT_errors[] = {
14824   { 0x00000000, "STATUS_SUCCESS" },
14825   { 0x00000000, "STATUS_WAIT_0" },
14826   { 0x00000001, "STATUS_WAIT_1" },
14827   { 0x00000002, "STATUS_WAIT_2" },
14828   { 0x00000003, "STATUS_WAIT_3" },
14829   { 0x0000003F, "STATUS_WAIT_63" },
14830   { 0x00000080, "STATUS_ABANDONED" },
14831   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
14832   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
14833   { 0x000000C0, "STATUS_USER_APC" },
14834   { 0x00000100, "STATUS_KERNEL_APC" },
14835   { 0x00000101, "STATUS_ALERTED" },
14836   { 0x00000102, "STATUS_TIMEOUT" },
14837   { 0x00000103, "STATUS_PENDING" },
14838   { 0x00000104, "STATUS_REPARSE" },
14839   { 0x00000105, "STATUS_MORE_ENTRIES" },
14840   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
14841   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
14842   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
14843   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
14844   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
14845   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
14846   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
14847   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
14848   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
14849   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
14850   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
14851   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
14852   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
14853   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
14854   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
14855   { 0x00000116, "STATUS_CRASH_DUMP" },
14856   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
14857   { 0x00000118, "STATUS_REPARSE_OBJECT" },
14858   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
14859   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
14860   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
14861   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
14862   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
14863   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
14864   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
14865   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
14866   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
14867   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
14868   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
14869   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
14870   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
14871   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
14872   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
14873   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
14874   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
14875   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
14876   { 0x40000012, "STATUS_EVENT_DONE" },
14877   { 0x40000013, "STATUS_EVENT_PENDING" },
14878   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
14879   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
14880   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
14881   { 0x40000017, "STATUS_WAS_UNLOCKED" },
14882   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
14883   { 0x40000019, "STATUS_WAS_LOCKED" },
14884   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
14885   { 0x4000001B, "STATUS_ALREADY_WIN32" },
14886   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
14887   { 0x4000001D, "STATUS_WX86_CONTINUE" },
14888   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
14889   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
14890   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
14891   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
14892   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
14893   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
14894   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
14895   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
14896   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
14897   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
14898   { 0x80000003, "STATUS_BREAKPOINT" },
14899   { 0x80000004, "STATUS_SINGLE_STEP" },
14900   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
14901   { 0x80000006, "STATUS_NO_MORE_FILES" },
14902   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
14903   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
14904   { 0x8000000B, "STATUS_NO_INHERITANCE" },
14905   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
14906   { 0x8000000D, "STATUS_PARTIAL_COPY" },
14907   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
14908   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
14909   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
14910   { 0x80000011, "STATUS_DEVICE_BUSY" },
14911   { 0x80000012, "STATUS_NO_MORE_EAS" },
14912   { 0x80000013, "STATUS_INVALID_EA_NAME" },
14913   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
14914   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
14915   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
14916   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
14917   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
14918   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
14919   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
14920   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
14921   { 0x8000001D, "STATUS_BUS_RESET" },
14922   { 0x8000001E, "STATUS_END_OF_MEDIA" },
14923   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
14924   { 0x80000020, "STATUS_MEDIA_CHECK" },
14925   { 0x80000021, "STATUS_SETMARK_DETECTED" },
14926   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
14927   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
14928   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
14929   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
14930   { 0x80000026, "STATUS_LONGJUMP" },
14931   { 0x80040111, "MAPI_E_LOGON_FAILED" },
14932   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
14933   { 0x80090301, "SEC_E_INVALID_HANDLE" },
14934   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
14935   { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
14936   { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
14937   { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
14938   { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
14939   { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
14940   { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
14941   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
14942   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
14943   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
14944   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
14945   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
14946   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
14947   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
14948   { 0xC0000008, "STATUS_INVALID_HANDLE" },
14949   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
14950   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
14951   { 0xC000000B, "STATUS_INVALID_CID" },
14952   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
14953   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
14954   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
14955   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
14956   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
14957   { 0xC0000011, "STATUS_END_OF_FILE" },
14958   { 0xC0000012, "STATUS_WRONG_VOLUME" },
14959   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
14960   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
14961   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
14962   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
14963   { 0xC0000017, "STATUS_NO_MEMORY" },
14964   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
14965   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
14966   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
14967   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
14968   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
14969   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
14970   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
14971   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
14972   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
14973   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
14974   { 0xC0000022, "STATUS_ACCESS_DENIED" },
14975   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
14976   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
14977   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
14978   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
14979   { 0xC0000027, "STATUS_UNWIND" },
14980   { 0xC0000028, "STATUS_BAD_STACK" },
14981   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
14982   { 0xC000002A, "STATUS_NOT_LOCKED" },
14983   { 0xC000002B, "STATUS_PARITY_ERROR" },
14984   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
14985   { 0xC000002D, "STATUS_NOT_COMMITTED" },
14986   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
14987   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
14988   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
14989   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
14990   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
14991   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
14992   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
14993   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
14994   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
14995   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
14996   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
14997   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
14998   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
14999   { 0xC000003C, "STATUS_DATA_OVERRUN" },
15000   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
15001   { 0xC000003E, "STATUS_DATA_ERROR" },
15002   { 0xC000003F, "STATUS_CRC_ERROR" },
15003   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
15004   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
15005   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
15006   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
15007   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
15008   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
15009   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
15010   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
15011   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
15012   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
15013   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
15014   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
15015   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
15016   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
15017   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
15018   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
15019   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
15020   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
15021   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
15022   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
15023   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
15024   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
15025   { 0xC0000056, "STATUS_DELETE_PENDING" },
15026   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
15027   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
15028   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
15029   { 0xC000005A, "STATUS_INVALID_OWNER" },
15030   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
15031   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
15032   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
15033   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
15034   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
15035   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
15036   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
15037   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
15038   { 0xC0000063, "STATUS_USER_EXISTS" },
15039   { 0xC0000064, "STATUS_NO_SUCH_USER" },
15040   { 0xC0000065, "STATUS_GROUP_EXISTS" },
15041   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
15042   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
15043   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
15044   { 0xC0000069, "STATUS_LAST_ADMIN" },
15045   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
15046   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
15047   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
15048   { 0xC000006D, "STATUS_LOGON_FAILURE" },
15049   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
15050   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
15051   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
15052   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
15053   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
15054   { 0xC0000073, "STATUS_NONE_MAPPED" },
15055   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
15056   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
15057   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
15058   { 0xC0000077, "STATUS_INVALID_ACL" },
15059   { 0xC0000078, "STATUS_INVALID_SID" },
15060   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
15061   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
15062   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
15063   { 0xC000007C, "STATUS_NO_TOKEN" },
15064   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
15065   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
15066   { 0xC000007F, "STATUS_DISK_FULL" },
15067   { 0xC0000080, "STATUS_SERVER_DISABLED" },
15068   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
15069   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
15070   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
15071   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
15072   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
15073   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
15074   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
15075   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
15076   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
15077   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
15078   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
15079   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
15080   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
15081   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
15082   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
15083   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
15084   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
15085   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
15086   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
15087   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
15088   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
15089   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
15090   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
15091   { 0xC0000098, "STATUS_FILE_INVALID" },
15092   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
15093   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
15094   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
15095   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
15096   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
15097   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
15098   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
15099   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
15100   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
15101   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
15102   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
15103   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
15104   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
15105   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
15106   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
15107   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
15108   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
15109   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
15110   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
15111   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
15112   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
15113   { 0xC00000AE, "STATUS_PIPE_BUSY" },
15114   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
15115   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
15116   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
15117   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
15118   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
15119   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
15120   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
15121   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
15122   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
15123   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
15124   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
15125   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
15126   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
15127   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
15128   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
15129   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
15130   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
15131   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
15132   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
15133   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
15134   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
15135   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
15136   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
15137   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
15138   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
15139   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
15140   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
15141   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
15142   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
15143   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
15144   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
15145   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
15146   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
15147   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
15148   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
15149   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
15150   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
15151   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
15152   { 0xC00000D5, "STATUS_FILE_RENAMED" },
15153   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
15154   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
15155   { 0xC00000D8, "STATUS_CANT_WAIT" },
15156   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
15157   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
15158   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
15159   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
15160   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
15161   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
15162   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
15163   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
15164   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
15165   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
15166   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
15167   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
15168   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
15169   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
15170   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
15171   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
15172   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
15173   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
15174   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
15175   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
15176   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
15177   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
15178   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
15179   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
15180   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
15181   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
15182   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
15183   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
15184   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
15185   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
15186   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
15187   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
15188   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
15189   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
15190   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
15191   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
15192   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
15193   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
15194   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
15195   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
15196   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
15197   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
15198   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
15199   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
15200   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
15201   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
15202   { 0xC0000107, "STATUS_FILES_OPEN" },
15203   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
15204   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
15205   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
15206   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
15207   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
15208   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
15209   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
15210   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
15211   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
15212   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
15213   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
15214   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
15215   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
15216   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
15217   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
15218   { 0xC0000117, "STATUS_NO_LDT" },
15219   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
15220   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
15221   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
15222   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
15223   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
15224   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
15225   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
15226   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
15227   { 0xC0000120, "STATUS_CANCELLED" },
15228   { 0xC0000121, "STATUS_CANNOT_DELETE" },
15229   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
15230   { 0xC0000123, "STATUS_FILE_DELETED" },
15231   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
15232   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
15233   { 0xC0000126, "STATUS_SPECIAL_USER" },
15234   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
15235   { 0xC0000128, "STATUS_FILE_CLOSED" },
15236   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
15237   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
15238   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
15239   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
15240   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
15241   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
15242   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
15243   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
15244   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
15245   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
15246   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
15247   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
15248   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
15249   { 0xC0000136, "STATUS_OPEN_FAILED" },
15250   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
15251   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
15252   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
15253   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
15254   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
15255   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
15256   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
15257   { 0xC000013E, "STATUS_LINK_FAILED" },
15258   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
15259   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
15260   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
15261   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
15262   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
15263   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
15264   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
15265   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
15266   { 0xC0000147, "STATUS_NO_PAGEFILE" },
15267   { 0xC0000148, "STATUS_INVALID_LEVEL" },
15268   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
15269   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
15270   { 0xC000014B, "STATUS_PIPE_BROKEN" },
15271   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
15272   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
15273   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
15274   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
15275   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
15276   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
15277   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
15278   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
15279   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
15280   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
15281   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
15282   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
15283   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
15284   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
15285   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
15286   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
15287   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
15288   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
15289   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
15290   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
15291   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
15292   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
15293   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
15294   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
15295   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
15296   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
15297   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
15298   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
15299   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
15300   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
15301   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
15302   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
15303   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
15304   { 0xC000016D, "STATUS_FT_ORPHANING" },
15305   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
15306   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
15307   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
15308   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
15309   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
15310   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
15311   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
15312   { 0xC0000178, "STATUS_NO_MEDIA" },
15313   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
15314   { 0xC000017B, "STATUS_INVALID_MEMBER" },
15315   { 0xC000017C, "STATUS_KEY_DELETED" },
15316   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
15317   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
15318   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
15319   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
15320   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
15321   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
15322   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
15323   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
15324   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
15325   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
15326   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
15327   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
15328   { 0xC0000189, "STATUS_TOO_LATE" },
15329   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
15330   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
15331   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
15332   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
15333   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
15334   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
15335   { 0xC0000190, "STATUS_TRUST_FAILURE" },
15336   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
15337   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
15338   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
15339   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
15340   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
15341   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
15342   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
15343   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
15344   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
15345   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
15346   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
15347   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
15348   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
15349   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
15350   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
15351   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
15352   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
15353   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
15354   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
15355   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
15356   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
15357   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
15358   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
15359   { 0xC000020D, "STATUS_CONNECTION_RESET" },
15360   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
15361   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
15362   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
15363   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
15364   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
15365   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
15366   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
15367   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
15368   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
15369   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
15370   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
15371   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
15372   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
15373   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
15374   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
15375   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
15376   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
15377   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
15378   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
15379   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
15380   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
15381   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
15382   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
15383   { 0xC0000225, "STATUS_NOT_FOUND" },
15384   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
15385   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
15386   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
15387   { 0xC0000229, "STATUS_FAIL_CHECK" },
15388   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
15389   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
15390   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
15391   { 0xC000022D, "STATUS_RETRY" },
15392   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
15393   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
15394   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
15395   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
15396   { 0xC0000232, "STATUS_INVALID_VARIANT" },
15397   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
15398   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
15399   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
15400   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
15401   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
15402   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
15403   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
15404   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
15405   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
15406   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
15407   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
15408   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
15409   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
15410   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
15411   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
15412   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
15413   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
15414   { 0xC0000244, "STATUS_AUDIT_FAILED" },
15415   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
15416   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
15417   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
15418   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
15419   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
15420   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
15421   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
15422   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
15423   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
15424   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
15425   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
15426   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
15427   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
15428   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
15429   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
15430   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
15431   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
15432   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
15433   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
15434   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
15435   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
15436   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
15437   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
15438   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
15439   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
15440   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
15441   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
15442   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
15443   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
15444   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
15445   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
15446   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
15447   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
15448   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
15449   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
15450   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
15451   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
15452   { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
15453   { 0xC0000272, "STATUS_NO_MATCH" },
15454   { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
15455   { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
15456   { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
15457   { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
15458   { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
15459   { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
15460   { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
15461   { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
15462   { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
15463   { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
15464   { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
15465   { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
15466   { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
15467   { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
15468   { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
15469   { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
15470   { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
15471   { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
15472   { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
15473   { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
15474   { 0xC000028E, "STATUS_NO_EFS" },
15475   { 0xC000028F, "STATUS_WRONG_EFS" },
15476   { 0xC0000290, "STATUS_NO_USER_KEYS" },
15477   { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
15478   { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
15479   { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
15480   { 0x40000294, "STATUS_WAKE_SYSTEM" },
15481   { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
15482   { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
15483   { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
15484   { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
15485   { 0xC0000299, "STATUS_SHARED_POLICY" },
15486   { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
15487   { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
15488   { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
15489   { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
15490   { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
15491   { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
15492   { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
15493   { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
15494   { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
15495   { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
15496   { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
15497   { 0xC00002A5, "STATUS_DS_BUSY" },
15498   { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
15499   { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
15500   { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
15501   { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
15502   { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
15503   { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
15504   { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
15505   { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
15506   { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
15507   { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
15508   { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
15509   { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
15510   { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
15511   { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
15512   { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
15513   { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
15514   { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
15515   { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
15516   { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
15517   { 0xC00002B9, "STATUS_NOINTERFACE" },
15518   { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
15519   { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
15520   { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
15521   { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
15522   { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
15523   { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
15524   { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
15525   { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
15526   { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
15527   { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
15528   { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
15529   { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
15530   { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
15531   { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
15532   { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
15533   { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
15534   { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
15535   { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
15536   { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
15537   { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
15538   { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
15539   { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
15540   { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
15541   { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
15542   { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
15543   { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
15544   { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
15545   { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
15546   { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
15547   { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
15548   { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
15549   { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
15550   { 0xC00002E1, "STATUS_DS_CANT_START" },
15551   { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
15552   { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
15553   { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
15554   { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
15555   { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
15556   { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
15557   { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
15558   { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
15559   { 0xC0009898, "STATUS_WOW_ASSERTION" },
15560   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
15561   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
15562   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
15563   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
15564   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
15565   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
15566   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
15567   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
15568   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
15569   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
15570   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
15571   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
15572   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
15573   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
15574   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
15575   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
15576   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
15577   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
15578   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
15579   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
15580   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
15581   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
15582   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
15583   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
15584   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
15585   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
15586   { 0xC002001B, "RPC_NT_CALL_FAILED" },
15587   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
15588   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
15589   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
15590   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
15591   { 0xC0020022, "RPC_NT_INVALID_TAG" },
15592   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
15593   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
15594   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
15595   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
15596   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
15597   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
15598   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
15599   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
15600   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
15601   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
15602   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
15603   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
15604   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
15605   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
15606   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
15607   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
15608   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
15609   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
15610   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
15611   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
15612   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
15613   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
15614   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
15615   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
15616   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
15617   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
15618   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
15619   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
15620   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
15621   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
15622   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
15623   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
15624   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
15625   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
15626   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
15627   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
15628   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
15629   { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
15630   { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
15631   { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
15632   { 0xC002100A, "RPC_P_SEND_FAILED" },
15633   { 0xC002100B, "RPC_P_TIMEOUT" },
15634   { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
15635   { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
15636   { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
15637   { 0xC0021015, "RPC_P_THREAD_LISTENING" },
15638   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
15639   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
15640   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
15641   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
15642   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
15643   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
15644   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
15645   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
15646   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
15647   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
15648   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
15649   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
15650   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
15651   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
15652   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
15653   { 0xC002004C, "EPT_NT_CANT_CREATE" },
15654   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
15655   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
15656   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
15657   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
15658   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
15659   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
15660   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
15661   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
15662   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
15663   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
15664   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
15665   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
15666   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
15667   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
15668   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
15669   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
15670   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
15671   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
15672   { 0,          NULL }
15673 };
15674
15675
15676
15677 static const true_false_string tfs_smb_flags_lock = {
15678         "Lock&Read, Write&Unlock are supported",
15679         "Lock&Read, Write&Unlock are not supported"
15680 };
15681 static const true_false_string tfs_smb_flags_receive_buffer = {
15682         "Receive buffer has been posted",
15683         "Receive buffer has not been posted"
15684 };
15685 static const true_false_string tfs_smb_flags_caseless = {
15686         "Path names are caseless",
15687         "Path names are case sensitive"
15688 };
15689 static const true_false_string tfs_smb_flags_canon = {
15690         "Pathnames are canonicalized",
15691         "Pathnames are not canonicalized"
15692 };
15693 static const true_false_string tfs_smb_flags_oplock = {
15694         "OpLock requested/granted",
15695         "OpLock not requested/granted"
15696 };
15697 static const true_false_string tfs_smb_flags_notify = {
15698         "Notify client on all modifications",
15699         "Notify client only on open"
15700 };
15701 static const true_false_string tfs_smb_flags_response = {
15702         "Message is a response to the client/redirector",
15703         "Message is a request to the server"
15704 };
15705
15706 static int
15707 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15708 {
15709         guint8 mask;
15710         proto_item *item = NULL;
15711         proto_tree *tree = NULL;
15712
15713         mask = tvb_get_guint8(tvb, offset);
15714
15715         if(parent_tree){
15716                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
15717                         "Flags: 0x%02x", mask);
15718                 tree = proto_item_add_subtree(item, ett_smb_flags);
15719         }
15720         proto_tree_add_boolean(tree, hf_smb_flags_response,
15721                 tvb, offset, 1, mask);
15722         proto_tree_add_boolean(tree, hf_smb_flags_notify,
15723                 tvb, offset, 1, mask);
15724         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
15725                 tvb, offset, 1, mask);
15726         proto_tree_add_boolean(tree, hf_smb_flags_canon,
15727                 tvb, offset, 1, mask);
15728         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
15729                 tvb, offset, 1, mask);
15730         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
15731                 tvb, offset, 1, mask);
15732         proto_tree_add_boolean(tree, hf_smb_flags_lock,
15733                 tvb, offset, 1, mask);
15734         offset += 1;
15735         return offset;
15736 }
15737
15738
15739
15740 static const true_false_string tfs_smb_flags2_long_names_allowed = {
15741         "Long file names are allowed in the response",
15742         "Long file names are not allowed in the response"
15743 };
15744 static const true_false_string tfs_smb_flags2_ea = {
15745         "Extended attributes are supported",
15746         "Extended attributes are not supported"
15747 };
15748 static const true_false_string tfs_smb_flags2_sec_sig = {
15749         "Security signatures are supported",
15750         "Security signatures are not supported"
15751 };
15752 static const true_false_string tfs_smb_flags2_long_names_used = {
15753         "Path names in request are long file names",
15754         "Path names in request are not long file names"
15755 };
15756 static const true_false_string tfs_smb_flags2_esn = {
15757         "Extended security negotiation is supported",
15758         "Extended security negotiation is not supported"
15759 };
15760 static const true_false_string tfs_smb_flags2_dfs = {
15761         "Resolve pathnames with Dfs",
15762         "Don't resolve pathnames with Dfs"
15763 };
15764 static const true_false_string tfs_smb_flags2_roe = {
15765         "Permit reads if execute-only",
15766         "Don't permit reads if execute-only"
15767 };
15768 static const true_false_string tfs_smb_flags2_nt_error = {
15769         "Error codes are NT error codes",
15770         "Error codes are DOS error codes"
15771 };
15772 static const true_false_string tfs_smb_flags2_string = {
15773         "Strings are Unicode",
15774         "Strings are ASCII"
15775 };
15776 static int
15777 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15778 {
15779         guint16 mask;
15780         proto_item *item = NULL;
15781         proto_tree *tree = NULL;
15782
15783         mask = tvb_get_letohs(tvb, offset);
15784
15785         if(parent_tree){
15786                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
15787                         "Flags2: 0x%04x", mask);
15788                 tree = proto_item_add_subtree(item, ett_smb_flags2);
15789         }
15790
15791         proto_tree_add_boolean(tree, hf_smb_flags2_string,
15792                 tvb, offset, 2, mask);
15793         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
15794                 tvb, offset, 2, mask);
15795         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
15796                 tvb, offset, 2, mask);
15797         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
15798                 tvb, offset, 2, mask);
15799         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
15800                 tvb, offset, 2, mask);
15801         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
15802                 tvb, offset, 2, mask);
15803         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
15804                 tvb, offset, 2, mask);
15805         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
15806                 tvb, offset, 2, mask);
15807         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
15808                 tvb, offset, 2, mask);
15809
15810         offset += 2;
15811         return offset;
15812 }
15813
15814
15815
15816 #define SMB_FLAGS_DIRN 0x80
15817
15818
15819 static void
15820 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
15821 {
15822         int offset = 0;
15823         proto_item *item = NULL, *hitem = NULL;
15824         proto_tree *tree = NULL, *htree = NULL;
15825         guint8          flags;
15826         guint16         flags2;
15827         static smb_info_t       si_arr[20];
15828         static int si_counter=0;
15829         smb_info_t              *si;
15830         smb_saved_info_t *sip = NULL;
15831         smb_saved_info_key_t key;
15832         smb_saved_info_key_t *new_key;
15833         guint32 nt_status = 0;
15834         guint8 errclass = 0;
15835         guint16 errcode = 0;
15836         guint32 pid_mid;
15837         conversation_t *conversation;
15838         nstime_t ns;
15839
15840         si_counter++;
15841         if(si_counter==20){
15842                 si_counter=0;
15843         }
15844         si=&si_arr[si_counter];
15845
15846         top_tree=parent_tree;
15847
15848         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
15849                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
15850         }
15851         if (check_col(pinfo->cinfo, COL_INFO)){
15852                 col_clear(pinfo->cinfo, COL_INFO);
15853         }
15854
15855         /* start off using the local variable, we will allocate a new one if we
15856            need to*/
15857         si->cmd = tvb_get_guint8(tvb, offset+4);
15858         flags = tvb_get_guint8(tvb, offset+9);
15859         /*
15860          * XXX - in some SMB-over-OSI-transport and SMB-over-Vines traffic,
15861          * the direction flag appears never to be set, even for what appear
15862          * to be replies.  Do some SMB servers fail to set that flag,
15863          * under the assumption that the client knows it's a reply because
15864          * it received it?
15865          */
15866         si->request = !(flags&SMB_FLAGS_DIRN);
15867         flags2 = tvb_get_letohs(tvb, offset+10);
15868         if(flags2 & 0x8000){
15869                 si->unicode = TRUE; /* Mark them as Unicode */
15870         } else {
15871                 si->unicode = FALSE;
15872         }
15873         si->tid = tvb_get_letohs(tvb, offset+24);
15874         si->pid = tvb_get_letohs(tvb, offset+26);
15875         si->uid = tvb_get_letohs(tvb, offset+28);
15876         si->mid = tvb_get_letohs(tvb, offset+30);
15877         pid_mid = (si->pid << 16) | si->mid;
15878         si->info_level = -1;
15879         si->info_count = -1;
15880
15881         if (parent_tree) {
15882                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
15883                         -1, FALSE);
15884                 tree = proto_item_add_subtree(item, ett_smb);
15885
15886                 hitem = proto_tree_add_text(tree, tvb, offset, 32,
15887                         "SMB Header");
15888
15889                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
15890         }
15891
15892         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
15893         offset += 4;  /* Skip the marker */
15894
15895         /* find which conversation we are part of and get the tables for that
15896            conversation*/
15897         conversation = find_conversation(&pinfo->src, &pinfo->dst,
15898                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
15899         if(!conversation){
15900                 /* OK this is a new conversation so lets create it */
15901                 conversation = conversation_new(&pinfo->src, &pinfo->dst,
15902                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
15903         }
15904         /* see if we already have the smb data for this conversation */
15905         si->ct=conversation_get_proto_data(conversation, proto_smb);
15906         if(!si->ct){
15907                 /* No, not yet. create it and attach it to the conversation */
15908                 si->ct = g_mem_chunk_alloc(conv_tables_chunk);
15909                 conv_tables = g_slist_prepend(conv_tables, si->ct);
15910                 si->ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
15911                         smb_saved_info_equal_matched);
15912                 si->ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
15913                         smb_saved_info_equal_unmatched);
15914                 si->ct->tid_service=g_hash_table_new(
15915                         smb_saved_info_hash_unmatched,
15916                         smb_saved_info_equal_unmatched);
15917                 conversation_add_proto_data(conversation, proto_smb, si->ct);
15918         }
15919
15920         if( (si->request)
15921             &&  (si->mid==0)
15922             &&  (si->uid==0)
15923             &&  (si->pid==0)
15924             &&  (si->tid==0) ){
15925                 /* this is a broadcast SMB packet, there will not be a reply.
15926                    We dont need to do anything
15927                 */
15928                 si->unidir = TRUE;
15929         } else if( (si->cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
15930                    ||(si->cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
15931                    ||(si->cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
15932                    ||(si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
15933                 /* Ok, we got a special request type. This request is either
15934                    an NT Cancel or a continuation relative to a real request
15935                    in an earlier packet.  In either case, we don't expect any
15936                    responses to this packet.  For continuations, any later
15937                    responses we see really just belong to the original request.
15938                    Anyway, we want to remember this packet somehow and
15939                    remember which original request it is associated with so
15940                    we can say nice things such as "This is a Cancellation to
15941                    the request in frame x", but we don't want the
15942                    request/response matching to get messed up.
15943
15944                    The only thing we do in this case is trying to find which original
15945                    request we match with and insert an entry for this "special"
15946                    request for later reference. We continue to reference the original
15947                    requests smb_saved_info_t but we dont touch it or change anything
15948                    in it.
15949                 */
15950
15951                 si->unidir = TRUE;  /*we dont expect an answer to this one*/
15952
15953                 if(!pinfo->fd->flags.visited){
15954                         /* try to find which original call we match and if we
15955                            find it add us to the matched table. Dont touch
15956                            anything else since we dont want this one to mess
15957                            up the request/response matching. We still consider
15958                            the initial call the real request and this is only
15959                            some sort of continuation.
15960                         */
15961                         /* we only check the unmatched table and assume that the
15962                            last seen MID matching ours is the right one.
15963                            This can fail but is better than nothing
15964                         */
15965                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
15966                         if(sip!=NULL){
15967                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15968                                 new_key->frame = pinfo->fd->num;
15969                                 new_key->pid_mid = pid_mid;
15970                                 g_hash_table_insert(si->ct->matched, new_key,
15971                                     sip);
15972                         }
15973                 } else {
15974                         /* we have seen this packet before; check the
15975                            matching table
15976                         */
15977                         key.frame = pinfo->fd->num;
15978                         key.pid_mid = pid_mid;
15979                         sip=g_hash_table_lookup(si->ct->matched, &key);
15980                         if(sip==NULL){
15981                         /*
15982                           We didn't find it.
15983                           Too bad, unfortunately there is not really much we can
15984                           do now since this means that we never saw the initial
15985                           request.
15986                          */
15987                         }
15988                 }
15989
15990
15991                 if(sip && sip->frame_req){
15992                         switch(si->cmd){
15993                         case SMB_COM_NT_CANCEL:
15994                                 proto_tree_add_uint(htree, hf_smb_cancel_to,
15995                                                     tvb, 0, 0, sip->frame_req);
15996                                 break;
15997                         case SMB_COM_TRANSACTION_SECONDARY:
15998                         case SMB_COM_TRANSACTION2_SECONDARY:
15999                         case SMB_COM_NT_TRANSACT_SECONDARY:
16000                                 proto_tree_add_uint(htree, hf_smb_continuation_to,
16001                                                     tvb, 0, 0, sip->frame_req);
16002                                 break;
16003                         }
16004                 } else {
16005                         switch(si->cmd){
16006                         case SMB_COM_NT_CANCEL:
16007                                 proto_tree_add_text(htree, tvb, 0, 0,
16008                                                     "Cancellation to: <unknown frame>");
16009                                 break;
16010                         case SMB_COM_TRANSACTION_SECONDARY:
16011                         case SMB_COM_TRANSACTION2_SECONDARY:
16012                         case SMB_COM_NT_TRANSACT_SECONDARY:
16013                                 proto_tree_add_text(htree, tvb, 0, 0,
16014                                                     "Continuation to: <unknown frame>");
16015                                 break;
16016                         }
16017                 }
16018         } else { /* normal bidirectional request or response */
16019                 si->unidir = FALSE;
16020
16021                 if(!pinfo->fd->flags.visited){
16022                         /* first see if we find an unmatched smb "equal" to
16023                            the current one
16024                         */
16025                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
16026                         if(sip!=NULL){
16027                                 gboolean cmd_match=FALSE;
16028
16029                                 /*
16030                                  * Make sure the SMB we found was the
16031                                  * same command, or a different command
16032                                  * that's another valid type of reply
16033                                  * to that command.
16034                                  */
16035                                 if(si->cmd==sip->cmd){
16036                                         cmd_match=TRUE;
16037                                 }
16038                                 else if(si->cmd==SMB_COM_NT_CANCEL){
16039                                         cmd_match=TRUE;
16040                                 }
16041                                 else if((si->cmd==SMB_COM_TRANSACTION_SECONDARY)
16042                                      && (sip->cmd==SMB_COM_TRANSACTION)){
16043                                         cmd_match=TRUE;
16044                                 }
16045                                 else if((si->cmd==SMB_COM_TRANSACTION2_SECONDARY)
16046                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
16047                                         cmd_match=TRUE;
16048                                 }
16049                                 else if((si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)
16050                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
16051                                         cmd_match=TRUE;
16052                                 }
16053
16054                                 if( (si->request) || (!cmd_match) ) {
16055                                         /* If we are processing an SMB request but there was already
16056                                            another "identical" smb resuest we had not matched yet.
16057                                            This must mean that either we have a retransmission or that the
16058                                            response to the previous one was lost and the client has reused
16059                                            the MID for this conversation. In either case it's not much more
16060                                            we can do than forget the old request and concentrate on the
16061                                            present one instead.
16062
16063                                            We also do this cleanup if we see that the cmd in the original
16064                                            request in sip->cmd is not compatible with the current cmd.
16065                                            This is to prevent matching errors such as if there were two
16066                                            SMBs of different cmds but with identical MID and PID values and
16067                                            if ethereal lost the first reply and the second request.
16068                                         */
16069                                         g_hash_table_remove(si->ct->unmatched, (void *)pid_mid);
16070                                         sip=NULL; /* XXX should free it as well */
16071                                 } else {
16072                                         /* we have found a response to some request we have seen earlier.
16073                                            What we do now depends on whether this is the first response
16074                                            to that request we see (id frame_res==0) or not.
16075                                         */
16076                                         if(sip->frame_res==0){
16077                                                 /* ok it is the first response we have seen to this packet */
16078                                                 sip->frame_res = pinfo->fd->num;
16079                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16080                                                 new_key->frame = sip->frame_res;
16081                                                 new_key->pid_mid = pid_mid;
16082                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16083                                         } else {
16084                                                 /* we have already seen another response to this one, but
16085                                                    register it anyway so we see which request it matches
16086                                                 */
16087                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16088                                                 new_key->frame = pinfo->fd->num;
16089                                                 new_key->pid_mid = pid_mid;
16090                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16091                                         }
16092                                 }
16093                         }
16094                         if(si->request){
16095                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
16096                                 sip->frame_req = pinfo->fd->num;
16097                                 sip->frame_res = 0;
16098                                 sip->req_time.secs=pinfo->fd->abs_secs;
16099                                 sip->req_time.nsecs=pinfo->fd->abs_usecs*1000;
16100                                 sip->flags = 0;
16101                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)
16102                                     == (void *)TID_IPC) {
16103                                         sip->flags |= SMB_SIF_TID_IS_IPC;
16104                                 }
16105                                 sip->cmd = si->cmd;
16106                                 sip->extra_info = NULL;
16107                                 g_hash_table_insert(si->ct->unmatched, (void *)pid_mid, sip);
16108                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16109                                 new_key->frame = sip->frame_req;
16110                                 new_key->pid_mid = pid_mid;
16111                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16112                         }
16113                 } else {
16114                         /* we have seen this packet before; check the
16115                            matching table.
16116                            If we haven't yet seen the reply, we won't
16117                            find the info for it; we don't need it, as
16118                            we only use it to save information, and, as
16119                            we've seen this packet before, we've already
16120                            saved the information.
16121                         */
16122                         key.frame = pinfo->fd->num;
16123                         key.pid_mid = pid_mid;
16124                         sip=g_hash_table_lookup(si->ct->matched, &key);
16125                 }
16126         }
16127
16128         /*
16129          * Pass the "sip" on to subdissectors through "si".
16130          */
16131         si->sip = sip;
16132
16133         if (sip != NULL) {
16134                 /*
16135                  * Put in fields for the frame number of the frame to which
16136                  * this is a response or the frame with the response to this
16137                  * frame - if we know the frame number (i.e., it's not 0).
16138                  */
16139                 if(si->request){
16140                         if (sip->frame_res != 0)
16141                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
16142                 } else {
16143                         if (sip->frame_req != 0) {
16144                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
16145                                 ns.secs = pinfo->fd->abs_secs - sip->req_time.secs;
16146                                 ns.nsecs = pinfo->fd->abs_usecs*1000 - sip->req_time.nsecs;
16147                                 if(ns.nsecs<0){
16148                                         ns.nsecs+=1000000000;
16149                                         ns.secs--;
16150                                 }
16151                                 proto_tree_add_time(htree, hf_smb_time, tvb,
16152                                     0, 0, &ns);
16153                         }
16154                 }
16155         }
16156
16157         /* smb command */
16158         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);
16159         offset += 1;
16160
16161         if(flags2 & 0x4000){
16162                 /* handle NT 32 bit error code */
16163
16164                 nt_status = tvb_get_letohl(tvb, offset);
16165
16166                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
16167                         TRUE);
16168                 offset += 4;
16169
16170         } else {
16171                 /* handle DOS error code & class */
16172                 errclass = tvb_get_guint8(tvb, offset);
16173                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
16174                         errclass);
16175                 offset += 1;
16176
16177                 /* reserved byte */
16178                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
16179                 offset += 1;
16180
16181                 /* error code */
16182                 /* XXX - the type of this field depends on the value of
16183                  * "errcls", so there is isn't a single value_string array
16184                  * fo it, so there can't be a single field for it.
16185                  */
16186                 errcode = tvb_get_letohs(tvb, offset);
16187                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
16188                         offset, 2, errcode, "Error Code: %s",
16189                         decode_smb_error(errclass, errcode));
16190                 offset += 2;
16191         }
16192
16193         /* flags */
16194         offset = dissect_smb_flags(tvb, htree, offset);
16195
16196         /* flags2 */
16197         offset = dissect_smb_flags2(tvb, htree, offset);
16198
16199         /*
16200          * The document at
16201          *
16202          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
16203          *
16204          * (a text version of "Microsoft Networks SMB FILE SHARING
16205          * PROTOCOL, Document Version 6.0p") says that:
16206          *
16207          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
16208          *      the "High Part of PID";
16209          *
16210          *      the next four bytes are reserved;
16211          *
16212          *      the next four bytes are, for SMB-over-IPX (with no
16213          *      NetBIOS involved) two bytes of Session ID and two bytes
16214          *      of SequenceNumber.
16215          *
16216          * Network Monitor 2.x dissects the four bytes before the Session ID
16217          * as a "Key", and the two bytes after the SequenceNumber as
16218          * a "Group ID".
16219          *
16220          * The "High Part of PID" has been seen in calls other than NT
16221          * Create and X, although most of them appear to be I/O on DCE RPC
16222          * pipes opened with the NT Create and X in question.
16223          */
16224         proto_tree_add_item(htree, hf_smb_pid_high, tvb, offset, 2, TRUE);
16225         offset += 2;
16226
16227         if (pinfo->ptype == PT_IPX &&
16228             (pinfo->match_port == IPX_SOCKET_NWLINK_SMB_SERVER ||
16229              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_REDIR ||
16230              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_MESSENGER)) {
16231                 /*
16232                  * This is SMB-over-IPX.
16233                  * XXX - do we have to worry about "sequenced commands",
16234                  * as per the Samba document?  They say that for
16235                  * "unsequenced commands" (with a sequence number of 0),
16236                  * the Mid must be unique, but perhaps the Mid doesn't
16237                  * have to be unique for sequenced commands.  In at least
16238                  * one capture with SMB-over-IPX, however, the Mids
16239                  * are unique even for sequenced commands.
16240                  */
16241                 /* Key */
16242                 proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
16243                     TRUE);
16244                 offset += 4;
16245
16246                 /* Session ID */
16247                 proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
16248                     TRUE);
16249                 offset += 2;
16250
16251                 /* Sequence number */
16252                 proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
16253                     TRUE);
16254                 offset += 2;
16255
16256                 /* Group ID */
16257                 proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
16258                     TRUE);
16259                 offset += 2;
16260         } else {
16261                 /*
16262                  * According to http://ubiqx.org/cifs/SMB.html#SMB.4.2.1
16263                  * and http://ubiqx.org/cifs/SMB.html#SMB.5.5.1 the 8
16264                  * bytes after the "High part of PID" are an 8-byte
16265                  * signature ...
16266                  */
16267                 proto_tree_add_item(htree, hf_smb_sig, tvb, offset, 8, TRUE);
16268                 offset += 8;
16269
16270                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2, TRUE);
16271                 offset += 2;
16272         }
16273
16274         /* TID */
16275         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si->tid);
16276         offset += 2;
16277
16278         /* PID */
16279         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
16280         offset += 2;
16281
16282         /* UID */
16283         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si->uid);
16284         offset += 2;
16285
16286         /* MID */
16287         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
16288         offset += 2;
16289
16290         pinfo->private_data = si;
16291
16292         /* tap the packet before the dissectors are called so we still get
16293            the tap listener called even if there is an exception.
16294         */
16295         tap_queue_packet(smb_tap, pinfo, si);
16296         dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE);
16297
16298         /* Append error info from this packet to info string. */
16299         if (!si->request && check_col(pinfo->cinfo, COL_INFO)) {
16300                 if (flags2 & 0x4000) {
16301                         /*
16302                          * The status is an NT status code; was there
16303                          * an error?
16304                          */
16305                         if ((nt_status & 0xC0000000) == 0xC0000000) {
16306                                 /*
16307                                  * Yes.
16308                                  */
16309                                 col_append_fstr(
16310                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16311                                         val_to_str(nt_status, NT_errors,
16312                                             "Unknown (0x%08X)"));
16313                         }
16314                 } else {
16315                         /*
16316                          * The status is a DOS error class and code; was
16317                          * there an error?
16318                          */
16319                         if (errclass != SMB_SUCCESS) {
16320                                 /*
16321                                  * Yes.
16322                                  */
16323                                 col_append_fstr(
16324                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16325                                         decode_smb_error(errclass, errcode));
16326                         }
16327                 }
16328         }
16329 }
16330
16331 static gboolean
16332 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16333 {
16334         /* must check that this really is a smb packet */
16335         if (!tvb_bytes_exist(tvb, 0, 4))
16336                 return FALSE;
16337
16338         if( (tvb_get_guint8(tvb, 0) != 0xff)
16339             || (tvb_get_guint8(tvb, 1) != 'S')
16340             || (tvb_get_guint8(tvb, 2) != 'M')
16341             || (tvb_get_guint8(tvb, 3) != 'B') ){
16342                 return FALSE;
16343         }
16344
16345         dissect_smb(tvb, pinfo, parent_tree);
16346         return TRUE;
16347 }
16348
16349 void
16350 proto_register_smb(void)
16351 {
16352         static hf_register_info hf[] = {
16353         { &hf_smb_cmd,
16354                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
16355                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
16356
16357         { &hf_smb_word_count,
16358                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
16359                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
16360
16361         { &hf_smb_byte_count,
16362                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
16363                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
16364
16365         { &hf_smb_response_to,
16366                 { "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
16367                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
16368
16369         { &hf_smb_time,
16370                 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
16371                 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
16372
16373         { &hf_smb_response_in,
16374                 { "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
16375                 NULL, 0, "The response to this packet is in this packet", HFILL }},
16376
16377         { &hf_smb_continuation_to,
16378                 { "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
16379                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
16380
16381         { &hf_smb_nt_status,
16382                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
16383                 VALS(NT_errors), 0, "NT Status code", HFILL }},
16384
16385         { &hf_smb_error_class,
16386                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
16387                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
16388
16389         { &hf_smb_error_code,
16390                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
16391                 NULL, 0, "DOS Error Code", HFILL }},
16392
16393         { &hf_smb_reserved,
16394                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
16395                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
16396
16397         { &hf_smb_sig,
16398                 { "Signature", "smb.signature", FT_BYTES, BASE_HEX,
16399                 NULL, 0, "Signature bytes", HFILL }},
16400
16401         { &hf_smb_key,
16402                 { "Key", "smb.key", FT_UINT32, BASE_HEX,
16403                 NULL, 0, "SMB-over-IPX Key", HFILL }},
16404
16405         { &hf_smb_session_id,
16406                 { "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
16407                 NULL, 0, "SMB-over-IPX Session ID", HFILL }},
16408
16409         { &hf_smb_sequence_num,
16410                 { "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
16411                 NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
16412
16413         { &hf_smb_group_id,
16414                 { "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
16415                 NULL, 0, "SMB-over-IPX Group ID", HFILL }},
16416
16417         { &hf_smb_pid,
16418                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
16419                 NULL, 0, "Process ID", HFILL }},
16420
16421         { &hf_smb_pid_high,
16422                 { "Process ID High", "smb.pid.high", FT_UINT16, BASE_DEC,
16423                 NULL, 0, "Process ID High Bytes", HFILL }},
16424
16425         { &hf_smb_tid,
16426                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
16427                 NULL, 0, "Tree ID", HFILL }},
16428
16429         { &hf_smb_uid,
16430                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
16431                 NULL, 0, "User ID", HFILL }},
16432
16433         { &hf_smb_mid,
16434                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
16435                 NULL, 0, "Multiplex ID", HFILL }},
16436
16437         { &hf_smb_flags_lock,
16438                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
16439                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
16440
16441         { &hf_smb_flags_receive_buffer,
16442                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
16443                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
16444
16445         { &hf_smb_flags_caseless,
16446                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
16447                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
16448
16449         { &hf_smb_flags_canon,
16450                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
16451                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
16452
16453         { &hf_smb_flags_oplock,
16454                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
16455                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
16456
16457         { &hf_smb_flags_notify,
16458                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
16459                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
16460
16461         { &hf_smb_flags_response,
16462                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
16463                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
16464
16465         { &hf_smb_flags2_long_names_allowed,
16466                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
16467                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
16468
16469         { &hf_smb_flags2_ea,
16470                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
16471                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
16472
16473         { &hf_smb_flags2_sec_sig,
16474                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
16475                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
16476
16477         { &hf_smb_flags2_long_names_used,
16478                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
16479                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
16480
16481         { &hf_smb_flags2_esn,
16482                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
16483                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
16484
16485         { &hf_smb_flags2_dfs,
16486                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
16487                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
16488
16489         { &hf_smb_flags2_roe,
16490                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
16491                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
16492
16493         { &hf_smb_flags2_nt_error,
16494                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
16495                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
16496
16497         { &hf_smb_flags2_string,
16498                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
16499                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
16500
16501         { &hf_smb_buffer_format,
16502                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
16503                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
16504
16505         { &hf_smb_dialect_name,
16506                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
16507                 NULL, 0, "Name of dialect", HFILL }},
16508
16509         { &hf_smb_dialect_index,
16510                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
16511                 NULL, 0, "Index of selected dialect", HFILL }},
16512
16513         { &hf_smb_max_trans_buf_size,
16514                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
16515                 NULL, 0, "Maximum transmit buffer size", HFILL }},
16516
16517         { &hf_smb_max_mpx_count,
16518                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
16519                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
16520
16521         { &hf_smb_max_vcs_num,
16522                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
16523                 NULL, 0, "Maximum VCs between client and server", HFILL }},
16524
16525         { &hf_smb_session_key,
16526                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
16527                 NULL, 0, "Unique token identifying this session", HFILL }},
16528
16529         { &hf_smb_server_timezone,
16530                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
16531                 NULL, 0, "Current timezone at server.", HFILL }},
16532
16533         { &hf_smb_encryption_key_length,
16534                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
16535                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
16536
16537         { &hf_smb_encryption_key,
16538                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
16539                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
16540
16541         { &hf_smb_primary_domain,
16542                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
16543                 NULL, 0, "The server's primary domain", HFILL }},
16544
16545         { &hf_smb_server,
16546                 { "Server", "smb.server", FT_STRING, BASE_NONE,
16547                 NULL, 0, "The name of the DC/server", HFILL }},
16548
16549         { &hf_smb_max_raw_buf_size,
16550                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
16551                 NULL, 0, "Maximum raw buffer size", HFILL }},
16552
16553         { &hf_smb_server_guid,
16554                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
16555                 NULL, 0, "Globally unique identifier for this server", HFILL }},
16556
16557         { &hf_smb_security_blob_len,
16558                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
16559                 NULL, 0, "Security blob length", HFILL }},
16560
16561         { &hf_smb_security_blob,
16562                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
16563                 NULL, 0, "Security blob", HFILL }},
16564
16565         { &hf_smb_sm_mode16,
16566                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
16567                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
16568
16569         { &hf_smb_sm_password16,
16570                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
16571                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
16572
16573         { &hf_smb_sm_mode,
16574                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
16575                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
16576
16577         { &hf_smb_sm_password,
16578                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
16579                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
16580
16581         { &hf_smb_sm_signatures,
16582                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
16583                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
16584
16585         { &hf_smb_sm_sig_required,
16586                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
16587                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
16588
16589         { &hf_smb_rm_read,
16590                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
16591                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
16592
16593         { &hf_smb_rm_write,
16594                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
16595                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
16596
16597         { &hf_smb_server_date_time,
16598                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
16599                 NULL, 0, "Current date and time at server", HFILL }},
16600
16601         { &hf_smb_server_smb_date,
16602                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
16603                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
16604
16605         { &hf_smb_server_smb_time,
16606                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
16607                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
16608
16609         { &hf_smb_server_cap_raw_mode,
16610                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
16611                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
16612
16613         { &hf_smb_server_cap_mpx_mode,
16614                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
16615                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
16616
16617         { &hf_smb_server_cap_unicode,
16618                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
16619                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
16620
16621         { &hf_smb_server_cap_large_files,
16622                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
16623                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
16624
16625         { &hf_smb_server_cap_nt_smbs,
16626                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
16627                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
16628
16629         { &hf_smb_server_cap_rpc_remote_apis,
16630                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
16631                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
16632
16633         { &hf_smb_server_cap_nt_status,
16634                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
16635                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
16636
16637         { &hf_smb_server_cap_level_ii_oplocks,
16638                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
16639                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
16640
16641         { &hf_smb_server_cap_lock_and_read,
16642                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
16643                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
16644
16645         { &hf_smb_server_cap_nt_find,
16646                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
16647                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
16648
16649         { &hf_smb_server_cap_dfs,
16650                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
16651                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
16652
16653         { &hf_smb_server_cap_infolevel_passthru,
16654                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
16655                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
16656
16657         { &hf_smb_server_cap_large_readx,
16658                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
16659                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
16660
16661         { &hf_smb_server_cap_large_writex,
16662                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
16663                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
16664
16665         { &hf_smb_server_cap_unix,
16666                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
16667                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
16668
16669         { &hf_smb_server_cap_reserved,
16670                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
16671                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
16672
16673         { &hf_smb_server_cap_bulk_transfer,
16674                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
16675                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
16676
16677         { &hf_smb_server_cap_compressed_data,
16678                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
16679                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
16680
16681         { &hf_smb_server_cap_extended_security,
16682                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
16683                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
16684
16685         { &hf_smb_system_time,
16686                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
16687                 NULL, 0, "System Time", HFILL }},
16688
16689         { &hf_smb_unknown,
16690                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
16691                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
16692
16693         { &hf_smb_dir_name,
16694                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
16695                 NULL, 0, "SMB Directory Name", HFILL }},
16696
16697         { &hf_smb_echo_count,
16698                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
16699                 NULL, 0, "Number of times to echo data back", HFILL }},
16700
16701         { &hf_smb_echo_data,
16702                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
16703                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
16704
16705         { &hf_smb_echo_seq_num,
16706                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
16707                 NULL, 0, "Sequence number for this echo response", HFILL }},
16708
16709         { &hf_smb_max_buf_size,
16710                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
16711                 NULL, 0, "Max client buffer size", HFILL }},
16712
16713         { &hf_smb_path,
16714                 { "Path", "smb.path", FT_STRING, BASE_NONE,
16715                 NULL, 0, "Path. Server name and share name", HFILL }},
16716
16717         { &hf_smb_service,
16718                 { "Service", "smb.service", FT_STRING, BASE_NONE,
16719                 NULL, 0, "Service name", HFILL }},
16720
16721         { &hf_smb_password,
16722                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
16723                 NULL, 0, "Password", HFILL }},
16724
16725         { &hf_smb_ansi_password,
16726                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
16727                 NULL, 0, "ANSI Password", HFILL }},
16728
16729         { &hf_smb_unicode_password,
16730                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
16731                 NULL, 0, "Unicode Password", HFILL }},
16732
16733         { &hf_smb_move_flags_file,
16734                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
16735                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
16736
16737         { &hf_smb_move_flags_dir,
16738                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
16739                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
16740
16741         { &hf_smb_move_flags_verify,
16742                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
16743                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
16744
16745         { &hf_smb_files_moved,
16746                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
16747                 NULL, 0, "Number of files moved", HFILL }},
16748
16749         { &hf_smb_copy_flags_file,
16750                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
16751                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
16752
16753         { &hf_smb_copy_flags_dir,
16754                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
16755                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
16756
16757         { &hf_smb_copy_flags_dest_mode,
16758                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
16759                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
16760
16761         { &hf_smb_copy_flags_source_mode,
16762                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
16763                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
16764
16765         { &hf_smb_copy_flags_verify,
16766                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
16767                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
16768
16769         { &hf_smb_copy_flags_tree_copy,
16770                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
16771                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
16772
16773         { &hf_smb_copy_flags_ea_action,
16774                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
16775                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
16776
16777         { &hf_smb_count,
16778                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
16779                 NULL, 0, "Count number of items/bytes", HFILL }},
16780
16781         { &hf_smb_file_name,
16782                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
16783                 NULL, 0, "File Name", HFILL }},
16784
16785         { &hf_smb_open_function_create,
16786                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
16787                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
16788
16789         { &hf_smb_open_function_open,
16790                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
16791                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
16792
16793         { &hf_smb_fid,
16794                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
16795                 NULL, 0, "FID: File ID", HFILL }},
16796
16797         { &hf_smb_file_attr_read_only_16bit,
16798                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
16799                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16800
16801         { &hf_smb_file_attr_read_only_8bit,
16802                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
16803                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16804
16805         { &hf_smb_file_attr_hidden_16bit,
16806                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
16807                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16808
16809         { &hf_smb_file_attr_hidden_8bit,
16810                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
16811                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16812
16813         { &hf_smb_file_attr_system_16bit,
16814                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
16815                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16816
16817         { &hf_smb_file_attr_system_8bit,
16818                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
16819                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16820
16821         { &hf_smb_file_attr_volume_16bit,
16822                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
16823                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
16824
16825         { &hf_smb_file_attr_volume_8bit,
16826                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
16827                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
16828
16829         { &hf_smb_file_attr_directory_16bit,
16830                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
16831                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16832
16833         { &hf_smb_file_attr_directory_8bit,
16834                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
16835                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16836
16837         { &hf_smb_file_attr_archive_16bit,
16838                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
16839                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16840
16841         { &hf_smb_file_attr_archive_8bit,
16842                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
16843                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16844
16845         { &hf_smb_file_attr_device,
16846                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
16847                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
16848
16849         { &hf_smb_file_attr_normal,
16850                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
16851                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
16852
16853         { &hf_smb_file_attr_temporary,
16854                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
16855                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
16856
16857         { &hf_smb_file_attr_sparse,
16858                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
16859                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
16860
16861         { &hf_smb_file_attr_reparse,
16862                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
16863                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
16864
16865         { &hf_smb_file_attr_compressed,
16866                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
16867                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
16868
16869         { &hf_smb_file_attr_offline,
16870                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
16871                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
16872
16873         { &hf_smb_file_attr_not_content_indexed,
16874                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
16875                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
16876
16877         { &hf_smb_file_attr_encrypted,
16878                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
16879                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
16880
16881         { &hf_smb_file_size,
16882                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
16883                 NULL, 0, "File Size", HFILL }},
16884
16885         { &hf_smb_search_attribute_read_only,
16886                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
16887                 TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
16888
16889         { &hf_smb_search_attribute_hidden,
16890                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
16891                 TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
16892
16893         { &hf_smb_search_attribute_system,
16894                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
16895                 TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
16896
16897         { &hf_smb_search_attribute_volume,
16898                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
16899                 TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
16900
16901         { &hf_smb_search_attribute_directory,
16902                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
16903                 TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
16904
16905         { &hf_smb_search_attribute_archive,
16906                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
16907                 TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
16908
16909         { &hf_smb_access_mode,
16910                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
16911                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
16912
16913         { &hf_smb_access_sharing,
16914                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
16915                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
16916
16917         { &hf_smb_access_locality,
16918                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
16919                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
16920
16921         { &hf_smb_access_caching,
16922                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
16923                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
16924
16925         { &hf_smb_access_writetru,
16926                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
16927                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
16928
16929         { &hf_smb_create_time,
16930                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
16931                 NULL, 0, "Creation Time", HFILL }},
16932
16933         { &hf_smb_modify_time,
16934                 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
16935                   NULL, 0, "Modification Time", HFILL }},
16936
16937         { &hf_smb_backup_time,
16938                 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
16939                   NULL, 0, "Backup time", HFILL}},
16940
16941         { &hf_smb_mac_alloc_block_count,
16942                 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
16943                   NULL, 0, "Allocation Block Count", HFILL}},
16944
16945         { &hf_smb_mac_alloc_block_size,
16946                 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
16947                   NULL, 0, "Allocation Block Size", HFILL}},
16948
16949         { &hf_smb_mac_free_block_count,
16950                 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
16951                   NULL, 0, "Free Block Count", HFILL}},
16952
16953         { &hf_smb_mac_root_file_count,
16954                 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
16955                 NULL, 0, "Root File Count", HFILL}},
16956
16957         { &hf_smb_mac_root_dir_count,
16958           { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
16959             NULL, 0, "Root Directory Count", HFILL}},
16960
16961         { &hf_smb_mac_file_count,
16962           { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
16963             NULL, 0, "File Count", HFILL}},
16964
16965         { &hf_smb_mac_dir_count,
16966           { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
16967             NULL, 0, "Directory Count", HFILL}},
16968
16969         { &hf_smb_mac_support_flags,
16970           { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
16971             NULL, 0, "Mac Support Flags", HFILL}},
16972
16973         { &hf_smb_mac_sup_access_ctrl,
16974           { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
16975             TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
16976
16977         { &hf_smb_mac_sup_getset_comments,
16978           { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
16979             TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
16980
16981         { &hf_smb_mac_sup_desktopdb_calls,
16982           { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
16983             TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
16984
16985         { &hf_smb_mac_sup_unique_ids,
16986           { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
16987             TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
16988
16989         { &hf_smb_mac_sup_streams,
16990           { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
16991             TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
16992
16993         { &hf_smb_create_dos_date,
16994                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
16995                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
16996
16997         { &hf_smb_create_dos_time,
16998                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
16999                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
17000
17001         { &hf_smb_last_write_time,
17002                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
17003                 NULL, 0, "Time this file was last written to", HFILL }},
17004
17005         { &hf_smb_last_write_dos_date,
17006                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
17007                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
17008
17009         { &hf_smb_last_write_dos_time,
17010                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
17011                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
17012
17013         { &hf_smb_old_file_name,
17014                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
17015                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
17016
17017         { &hf_smb_offset,
17018                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
17019                 NULL, 0, "Offset in file", HFILL }},
17020
17021         { &hf_smb_remaining,
17022                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
17023                 NULL, 0, "Remaining number of bytes", HFILL }},
17024
17025         { &hf_smb_padding,
17026                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
17027                 NULL, 0, "Padding or unknown data", HFILL }},
17028
17029         { &hf_smb_file_data,
17030                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
17031                 NULL, 0, "Data read/written to the file", HFILL }},
17032
17033         { &hf_smb_mac_fndrinfo,
17034                 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_HEX,
17035                   NULL, 0, "Finder Info", HFILL}},
17036
17037         { &hf_smb_total_data_len,
17038                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
17039                 NULL, 0, "Total length of data", HFILL }},
17040
17041         { &hf_smb_data_len,
17042                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
17043                 NULL, 0, "Length of data", HFILL }},
17044
17045         { &hf_smb_seek_mode,
17046                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
17047                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
17048
17049         { &hf_smb_access_time,
17050                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
17051                 NULL, 0, "Last Access Time", HFILL }},
17052
17053         { &hf_smb_access_dos_date,
17054                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
17055                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
17056
17057         { &hf_smb_access_dos_time,
17058                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
17059                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
17060
17061         { &hf_smb_data_size,
17062                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
17063                 NULL, 0, "Data Size", HFILL }},
17064
17065         { &hf_smb_alloc_size,
17066                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
17067                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17068
17069         { &hf_smb_max_count,
17070                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
17071                 NULL, 0, "Maximum Count", HFILL }},
17072
17073         { &hf_smb_min_count,
17074                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
17075                 NULL, 0, "Minimum Count", HFILL }},
17076
17077         { &hf_smb_timeout,
17078                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
17079                 NULL, 0, "Timeout in miliseconds", HFILL }},
17080
17081         { &hf_smb_high_offset,
17082                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
17083                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
17084
17085         { &hf_smb_units,
17086                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
17087                 NULL, 0, "Total number of units at server", HFILL }},
17088
17089         { &hf_smb_bpu,
17090                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
17091                 NULL, 0, "Blocks per unit at server", HFILL }},
17092
17093         { &hf_smb_blocksize,
17094                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
17095                 NULL, 0, "Block size (in bytes) at server", HFILL }},
17096
17097         { &hf_smb_freeunits,
17098                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
17099                 NULL, 0, "Number of free units at server", HFILL }},
17100
17101         { &hf_smb_data_offset,
17102                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17103                 NULL, 0, "Data Offset", HFILL }},
17104
17105         { &hf_smb_dcm,
17106                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
17107                 NULL, 0, "Data Compaction Mode", HFILL }},
17108
17109         { &hf_smb_request_mask,
17110                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
17111                 NULL, 0, "Connectionless mode mask", HFILL }},
17112
17113         { &hf_smb_response_mask,
17114                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
17115                 NULL, 0, "Connectionless mode mask", HFILL }},
17116
17117         { &hf_smb_search_id,
17118                 { "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
17119                 NULL, 0, "Search ID, handle for find operations", HFILL }},
17120
17121         { &hf_smb_write_mode_write_through,
17122                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
17123                 TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
17124
17125         { &hf_smb_write_mode_return_remaining,
17126                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
17127                 TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
17128
17129         { &hf_smb_write_mode_raw,
17130                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
17131                 TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
17132
17133         { &hf_smb_write_mode_message_start,
17134                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
17135                 TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
17136
17137         { &hf_smb_write_mode_connectionless,
17138                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
17139                 TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
17140
17141         { &hf_smb_resume_key_len,
17142                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
17143                 NULL, 0, "Resume Key length", HFILL }},
17144
17145         { &hf_smb_resume_find_id,
17146                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
17147                 NULL, 0, "Handle for Find operation", HFILL }},
17148
17149         { &hf_smb_resume_server_cookie,
17150                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
17151                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
17152
17153         { &hf_smb_resume_client_cookie,
17154                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
17155                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
17156
17157         { &hf_smb_andxoffset,
17158                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
17159                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
17160
17161         { &hf_smb_lock_type_large,
17162                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
17163                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
17164
17165         { &hf_smb_lock_type_cancel,
17166                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
17167                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
17168
17169         { &hf_smb_lock_type_change,
17170                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
17171                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
17172
17173         { &hf_smb_lock_type_oplock,
17174                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
17175                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
17176
17177         { &hf_smb_lock_type_shared,
17178                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
17179                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
17180
17181         { &hf_smb_locking_ol,
17182                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
17183                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
17184
17185         { &hf_smb_number_of_locks,
17186                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
17187                 NULL, 0, "Number of lock requests in this request", HFILL }},
17188
17189         { &hf_smb_number_of_unlocks,
17190                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
17191                 NULL, 0, "Number of unlock requests in this request", HFILL }},
17192
17193         { &hf_smb_lock_long_length,
17194                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
17195                 NULL, 0, "Length of lock/unlock region", HFILL }},
17196
17197         { &hf_smb_lock_long_offset,
17198                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
17199                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
17200
17201         { &hf_smb_file_type,
17202                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
17203                 VALS(filetype_vals), 0, "Type of file", HFILL }},
17204
17205         { &hf_smb_ipc_state_nonblocking,
17206                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
17207                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
17208
17209         { &hf_smb_ipc_state_endpoint,
17210                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
17211                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
17212
17213         { &hf_smb_ipc_state_pipe_type,
17214                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
17215                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
17216
17217         { &hf_smb_ipc_state_read_mode,
17218                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
17219                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
17220
17221         { &hf_smb_ipc_state_icount,
17222                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
17223                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
17224
17225         { &hf_smb_server_fid,
17226                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
17227                 NULL, 0, "Server unique File ID", HFILL }},
17228
17229         { &hf_smb_open_flags_add_info,
17230                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
17231                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
17232
17233         { &hf_smb_open_flags_ex_oplock,
17234                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
17235                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
17236
17237         { &hf_smb_open_flags_batch_oplock,
17238                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
17239                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
17240
17241         { &hf_smb_open_flags_ealen,
17242                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
17243                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
17244
17245         { &hf_smb_open_action_open,
17246                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
17247                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
17248
17249         { &hf_smb_open_action_lock,
17250                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
17251                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
17252
17253         { &hf_smb_vc_num,
17254                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
17255                 NULL, 0, "VC Number", HFILL }},
17256
17257         { &hf_smb_password_len,
17258                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
17259                 NULL, 0, "Length of password", HFILL }},
17260
17261         { &hf_smb_ansi_password_len,
17262                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
17263                 NULL, 0, "Length of ANSI password", HFILL }},
17264
17265         { &hf_smb_unicode_password_len,
17266                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
17267                 NULL, 0, "Length of Unicode password", HFILL }},
17268
17269         { &hf_smb_account,
17270                 { "Account", "smb.account", FT_STRING, BASE_NONE,
17271                 NULL, 0, "Account, username", HFILL }},
17272
17273         { &hf_smb_os,
17274                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
17275                 NULL, 0, "Which OS we are running", HFILL }},
17276
17277         { &hf_smb_lanman,
17278                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
17279                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
17280
17281         { &hf_smb_setup_action_guest,
17282                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
17283                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
17284
17285         { &hf_smb_fs,
17286                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
17287                 NULL, 0, "Native File System", HFILL }},
17288
17289         { &hf_smb_connect_flags_dtid,
17290                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
17291                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
17292
17293         { &hf_smb_connect_support_search,
17294                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
17295                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
17296
17297         { &hf_smb_connect_support_in_dfs,
17298                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
17299                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
17300
17301         { &hf_smb_max_setup_count,
17302                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
17303                 NULL, 0, "Maximum number of setup words to return", HFILL }},
17304
17305         { &hf_smb_total_param_count,
17306                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
17307                 NULL, 0, "Total number of parameter bytes", HFILL }},
17308
17309         { &hf_smb_total_data_count,
17310                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
17311                 NULL, 0, "Total number of data bytes", HFILL }},
17312
17313         { &hf_smb_max_param_count,
17314                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
17315                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
17316
17317         { &hf_smb_max_data_count,
17318                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
17319                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
17320
17321         { &hf_smb_param_disp16,
17322                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
17323                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17324
17325         { &hf_smb_param_count16,
17326                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
17327                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17328
17329         { &hf_smb_param_offset16,
17330                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
17331                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17332
17333         { &hf_smb_param_disp32,
17334                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
17335                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17336
17337         { &hf_smb_param_count32,
17338                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
17339                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17340
17341         { &hf_smb_param_offset32,
17342                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
17343                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17344
17345         { &hf_smb_data_count16,
17346                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
17347                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17348
17349         { &hf_smb_data_disp16,
17350                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
17351                 NULL, 0, "Data Displacement", HFILL }},
17352
17353         { &hf_smb_data_offset16,
17354                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17355                 NULL, 0, "Data Offset", HFILL }},
17356
17357         { &hf_smb_data_count32,
17358                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
17359                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17360
17361         { &hf_smb_data_disp32,
17362                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
17363                 NULL, 0, "Data Displacement", HFILL }},
17364
17365         { &hf_smb_data_offset32,
17366                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
17367                 NULL, 0, "Data Offset", HFILL }},
17368
17369         { &hf_smb_setup_count,
17370                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
17371                 NULL, 0, "Number of setup words in this buffer", HFILL }},
17372
17373         { &hf_smb_nt_trans_subcmd,
17374                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
17375                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
17376
17377         { &hf_smb_nt_ioctl_function_code,
17378                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
17379                 NULL, 0, "NT IOCTL function code", HFILL }},
17380
17381         { &hf_smb_nt_ioctl_isfsctl,
17382                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
17383                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
17384
17385         { &hf_smb_nt_ioctl_flags_root_handle,
17386                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
17387                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
17388
17389         { &hf_smb_nt_ioctl_data,
17390                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
17391                 NULL, 0, "Data for the IOCTL call", HFILL }},
17392
17393         { &hf_smb_nt_notify_action,
17394                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
17395                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
17396
17397         { &hf_smb_nt_notify_watch_tree,
17398                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
17399                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
17400
17401         { &hf_smb_nt_notify_stream_write,
17402                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
17403                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
17404
17405         { &hf_smb_nt_notify_stream_size,
17406                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
17407                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
17408
17409         { &hf_smb_nt_notify_stream_name,
17410                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
17411                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
17412
17413         { &hf_smb_nt_notify_security,
17414                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
17415                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
17416
17417         { &hf_smb_nt_notify_ea,
17418                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
17419                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
17420
17421         { &hf_smb_nt_notify_creation,
17422                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
17423                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
17424
17425         { &hf_smb_nt_notify_last_access,
17426                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
17427                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
17428
17429         { &hf_smb_nt_notify_last_write,
17430                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
17431                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
17432
17433         { &hf_smb_nt_notify_size,
17434                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
17435                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
17436
17437         { &hf_smb_nt_notify_attributes,
17438                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
17439                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
17440
17441         { &hf_smb_nt_notify_dir_name,
17442                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
17443                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
17444
17445         { &hf_smb_nt_notify_file_name,
17446                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
17447                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
17448
17449         { &hf_smb_root_dir_fid,
17450                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
17451                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
17452
17453         { &hf_smb_alloc_size64,
17454                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
17455                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17456
17457         { &hf_smb_nt_create_disposition,
17458                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
17459                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
17460
17461         { &hf_smb_sd_length,
17462                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
17463                 NULL, 0, "Total length of security descriptor", HFILL }},
17464
17465         { &hf_smb_ea_list_length,
17466                 { "EA List Length", "smb.ea.list_length", FT_UINT32, BASE_DEC,
17467                 NULL, 0, "Total length of extended attributes", HFILL }},
17468
17469         { &hf_smb_ea_flags,
17470                 { "EA Flags", "smb.ea.flags", FT_UINT8, BASE_HEX,
17471                 NULL, 0, "EA Flags", HFILL }},
17472
17473         { &hf_smb_ea_name_length,
17474                 { "EA Name Length", "smb.ea.name_length", FT_UINT8, BASE_DEC,
17475                 NULL, 0, "EA Name Length", HFILL }},
17476
17477         { &hf_smb_ea_data_length,
17478                 { "EA Data Length", "smb.ea.data_length", FT_UINT16, BASE_DEC,
17479                 NULL, 0, "EA Data Length", HFILL }},
17480
17481         { &hf_smb_ea_name,
17482                 { "EA Name", "smb.ea.name", FT_STRING, BASE_NONE,
17483                 NULL, 0, "EA Name", HFILL }},
17484
17485         { &hf_smb_ea_data,
17486                 { "EA Data", "smb.ea.data", FT_BYTES, BASE_NONE,
17487                 NULL, 0, "EA Data", HFILL }},
17488
17489         { &hf_smb_file_name_len,
17490                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
17491                 NULL, 0, "Length of File Name", HFILL }},
17492
17493         { &hf_smb_nt_impersonation_level,
17494                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
17495                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
17496
17497         { &hf_smb_nt_security_flags_context_tracking,
17498                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
17499                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
17500
17501         { &hf_smb_nt_security_flags_effective_only,
17502                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
17503                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
17504
17505         { &hf_smb_nt_access_mask_generic_read,
17506                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
17507                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
17508
17509         { &hf_smb_nt_access_mask_generic_write,
17510                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
17511                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
17512
17513         { &hf_smb_nt_access_mask_generic_execute,
17514                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
17515                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
17516
17517         { &hf_smb_nt_access_mask_generic_all,
17518                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
17519                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
17520
17521         { &hf_smb_nt_access_mask_maximum_allowed,
17522                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
17523                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
17524
17525         { &hf_smb_nt_access_mask_system_security,
17526                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
17527                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
17528
17529         { &hf_smb_nt_access_mask_synchronize,
17530                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
17531                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
17532
17533         { &hf_smb_nt_access_mask_write_owner,
17534                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
17535                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
17536
17537         { &hf_smb_nt_access_mask_write_dac,
17538                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
17539                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
17540
17541         { &hf_smb_nt_access_mask_read_control,
17542                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
17543                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
17544
17545         { &hf_smb_nt_access_mask_delete,
17546                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
17547                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
17548
17549         { &hf_smb_nt_access_mask_write_attributes,
17550                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
17551                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
17552
17553         { &hf_smb_nt_access_mask_read_attributes,
17554                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
17555                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
17556
17557         { &hf_smb_nt_access_mask_delete_child,
17558                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
17559                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
17560
17561         /*
17562          * "Execute" for files, "traverse" for directories.
17563          */
17564         { &hf_smb_nt_access_mask_execute,
17565                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
17566                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
17567
17568         { &hf_smb_nt_access_mask_write_ea,
17569                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
17570                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
17571
17572         { &hf_smb_nt_access_mask_read_ea,
17573                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
17574                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
17575
17576         /*
17577          * "Append data" for files, "add subdirectory" for directories,
17578          * "create pipe instance" for named pipes.
17579          */
17580         { &hf_smb_nt_access_mask_append,
17581                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
17582                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
17583
17584         /*
17585          * "Write data" for files and pipes, "add file" for directory.
17586          */
17587         { &hf_smb_nt_access_mask_write,
17588                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
17589                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
17590
17591         /*
17592          * "Read data" for files and pipes, "list directory" for directory.
17593          */
17594         { &hf_smb_nt_access_mask_read,
17595                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
17596                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
17597
17598         { &hf_smb_nt_create_bits_oplock,
17599                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
17600                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
17601
17602         { &hf_smb_nt_create_bits_boplock,
17603                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
17604                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
17605
17606         { &hf_smb_nt_create_bits_dir,
17607                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
17608                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
17609
17610         { &hf_smb_nt_create_bits_ext_resp,
17611           { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32, 
17612             TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
17613
17614         { &hf_smb_nt_create_options_directory_file,
17615                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
17616                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
17617
17618         { &hf_smb_nt_create_options_write_through,
17619                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
17620                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
17621
17622         { &hf_smb_nt_create_options_sequential_only,
17623                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
17624                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
17625
17626         { &hf_smb_nt_create_options_sync_io_alert,
17627                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
17628                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
17629
17630         { &hf_smb_nt_create_options_sync_io_nonalert,
17631                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
17632                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
17633
17634         { &hf_smb_nt_create_options_non_directory_file,
17635                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
17636                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
17637
17638         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
17639            and "NtOpenFile()"; is that sent over the wire?  Network
17640            Monitor thinks so, but its author may just have grabbed
17641            the flag bits from a system header file. */
17642
17643         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
17644            and "NtOpenFile()"; is that sent over the wire?  NetMon
17645            thinks so, but see previous comment. */
17646
17647         { &hf_smb_nt_create_options_no_ea_knowledge,
17648                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
17649                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
17650
17651         { &hf_smb_nt_create_options_eight_dot_three_only,
17652                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
17653                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
17654
17655         { &hf_smb_nt_create_options_random_access,
17656                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
17657                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
17658
17659         { &hf_smb_nt_create_options_delete_on_close,
17660                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
17661                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
17662
17663         /* 0x00002000 is "open by FID", or something such as that (which
17664            I suspect is like "open by inumber" on UNIX), at least in
17665            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
17666            wire?  NetMon thinks so, but see previous comment. */
17667
17668         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
17669            and "NtOpenFile()"; is that sent over the wire?  NetMon
17670            thinks so, but see previous comment. */
17671
17672         { &hf_smb_nt_share_access_read,
17673                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
17674                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
17675
17676         { &hf_smb_nt_share_access_write,
17677                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
17678                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
17679
17680         { &hf_smb_nt_share_access_delete,
17681                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
17682                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
17683
17684         { &hf_smb_file_eattr_read_only,
17685                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
17686                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17687
17688         { &hf_smb_file_eattr_hidden,
17689                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
17690                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17691
17692         { &hf_smb_file_eattr_system,
17693                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
17694                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17695
17696         { &hf_smb_file_eattr_volume,
17697                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
17698                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
17699
17700         { &hf_smb_file_eattr_directory,
17701                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
17702                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17703
17704         { &hf_smb_file_eattr_archive,
17705                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
17706                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17707
17708         { &hf_smb_file_eattr_device,
17709                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
17710                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
17711
17712         { &hf_smb_file_eattr_normal,
17713                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
17714                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
17715
17716         { &hf_smb_file_eattr_temporary,
17717                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
17718                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
17719
17720         { &hf_smb_file_eattr_sparse,
17721                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
17722                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
17723
17724         { &hf_smb_file_eattr_reparse,
17725                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
17726                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
17727
17728         { &hf_smb_file_eattr_compressed,
17729                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
17730                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
17731
17732         { &hf_smb_file_eattr_offline,
17733                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
17734                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
17735
17736         { &hf_smb_file_eattr_not_content_indexed,
17737                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
17738                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
17739
17740         { &hf_smb_file_eattr_encrypted,
17741                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
17742                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
17743
17744         { &hf_smb_sec_desc_len,
17745                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
17746                 NULL, 0, "Security Descriptor Length", HFILL }},
17747
17748         { &hf_smb_nt_qsd_owner,
17749                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
17750                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
17751
17752         { &hf_smb_nt_qsd_group,
17753                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
17754                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
17755
17756         { &hf_smb_nt_qsd_dacl,
17757                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
17758                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
17759
17760         { &hf_smb_nt_qsd_sacl,
17761                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
17762                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
17763
17764         { &hf_smb_extended_attributes,
17765                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
17766                 NULL, 0, "Extended Attributes", HFILL }},
17767
17768         { &hf_smb_oplock_level,
17769                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
17770                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
17771
17772         { &hf_smb_create_action,
17773                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
17774                 VALS(oa_open_vals), 0, "Type of action taken", HFILL }},
17775
17776         { &hf_smb_file_id,
17777                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
17778                 NULL, 0, "Server unique file ID", HFILL }},
17779
17780         { &hf_smb_ea_error_offset,
17781                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
17782                 NULL, 0, "Offset into EA list if EA error", HFILL }},
17783
17784         { &hf_smb_end_of_file,
17785                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
17786                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
17787
17788         { &hf_smb_device_type,
17789                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
17790                 VALS(device_type_vals), 0, "Type of device", HFILL }},
17791
17792         { &hf_smb_is_directory,
17793                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
17794                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
17795
17796         { &hf_smb_next_entry_offset,
17797                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
17798                 NULL, 0, "Offset to next entry", HFILL }},
17799
17800         { &hf_smb_change_time,
17801                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
17802                 NULL, 0, "Last Change Time", HFILL }},
17803
17804         { &hf_smb_setup_len,
17805                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
17806                 NULL, 0, "Length of printer setup data", HFILL }},
17807
17808         { &hf_smb_print_mode,
17809                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
17810                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
17811
17812         { &hf_smb_print_identifier,
17813                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
17814                 NULL, 0, "Identifier string for this print job", HFILL }},
17815
17816         { &hf_smb_restart_index,
17817                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
17818                 NULL, 0, "Index of entry after last returned", HFILL }},
17819
17820         { &hf_smb_print_queue_date,
17821                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
17822                 NULL, 0, "Date when this entry was queued", HFILL }},
17823
17824         { &hf_smb_print_queue_dos_date,
17825                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
17826                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
17827
17828         { &hf_smb_print_queue_dos_time,
17829                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
17830                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
17831
17832         { &hf_smb_print_status,
17833                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
17834                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
17835
17836         { &hf_smb_print_spool_file_number,
17837                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
17838                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
17839
17840         { &hf_smb_print_spool_file_size,
17841                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
17842                 NULL, 0, "Number of bytes in spool file", HFILL }},
17843
17844         { &hf_smb_print_spool_file_name,
17845                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
17846                 NULL, 0, "Name of client that submitted this job", HFILL }},
17847
17848         { &hf_smb_start_index,
17849                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
17850                 NULL, 0, "First queue entry to return", HFILL }},
17851
17852         { &hf_smb_originator_name,
17853                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
17854                 NULL, 0, "Name of sender of message", HFILL }},
17855
17856         { &hf_smb_destination_name,
17857                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
17858                 NULL, 0, "Name of recipient of message", HFILL }},
17859
17860         { &hf_smb_message_len,
17861                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
17862                 NULL, 0, "Length of message", HFILL }},
17863
17864         { &hf_smb_message,
17865                 { "Message", "smb.message", FT_STRING, BASE_NONE,
17866                 NULL, 0, "Message text", HFILL }},
17867
17868         { &hf_smb_mgid,
17869                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
17870                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
17871
17872         { &hf_smb_forwarded_name,
17873                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
17874                 NULL, 0, "Recipient name being forwarded", HFILL }},
17875
17876         { &hf_smb_machine_name,
17877                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
17878                 NULL, 0, "Name of target machine", HFILL }},
17879
17880         { &hf_smb_cancel_to,
17881                 { "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
17882                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
17883
17884         { &hf_smb_trans2_subcmd,
17885                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
17886                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
17887
17888         { &hf_smb_trans_name,
17889                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
17890                 NULL, 0, "Name of transaction", HFILL }},
17891
17892         { &hf_smb_transaction_flags_dtid,
17893                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
17894                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
17895
17896         { &hf_smb_transaction_flags_owt,
17897                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
17898                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
17899
17900         { &hf_smb_search_count,
17901                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
17902                 NULL, 0, "Maximum number of search entries to return", HFILL }},
17903
17904         { &hf_smb_search_pattern,
17905                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
17906                 NULL, 0, "Search Pattern", HFILL }},
17907
17908         { &hf_smb_ff2_backup,
17909                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
17910                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
17911
17912         { &hf_smb_ff2_continue,
17913                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
17914                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
17915
17916         { &hf_smb_ff2_resume,
17917                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
17918                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
17919
17920         { &hf_smb_ff2_close_eos,
17921                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
17922                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
17923
17924         { &hf_smb_ff2_close,
17925                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
17926                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
17927
17928         { &hf_smb_ff2_information_level,
17929                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
17930                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
17931
17932         { &hf_smb_qpi_loi,
17933                 { "Level of Interest", "smb.qpi_loi", FT_UINT16, BASE_DEC,
17934                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] QUERY_{FILE,PATH}_INFO commands", HFILL }},
17935
17936         { &hf_smb_spi_loi,
17937                 { "Level of Interest", "smb.spi_loi", FT_UINT16, BASE_DEC,
17938                 VALS(spi_loi_vals), 0, "Level of interest for TRANSACTION[2] SET_{FILE,PATH}_INFO commands", HFILL }},
17939
17940 #if 0
17941         { &hf_smb_sfi_writetru,
17942                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
17943                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
17944
17945         { &hf_smb_sfi_caching,
17946                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
17947                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
17948 #endif
17949
17950         { &hf_smb_storage_type,
17951                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
17952                 NULL, 0, "Type of storage", HFILL }},
17953
17954         { &hf_smb_resume,
17955                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
17956                 NULL, 0, "Resume Key", HFILL }},
17957
17958         { &hf_smb_max_referral_level,
17959                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
17960                 NULL, 0, "Latest referral version number understood", HFILL }},
17961
17962         { &hf_smb_qfsi_information_level,
17963                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_HEX,
17964                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
17965
17966         { &hf_smb_nt_rename_level,
17967                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
17968                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
17969
17970         { &hf_smb_cluster_count,
17971                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
17972                 NULL, 0, "Number of clusters", HFILL }},
17973
17974         { &hf_smb_number_of_links,
17975                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
17976                 NULL, 0, "Number of hard links to the file", HFILL }},
17977
17978         { &hf_smb_delete_pending,
17979                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
17980                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
17981
17982         { &hf_smb_index_number,
17983                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
17984                 NULL, 0, "File system unique identifier", HFILL }},
17985
17986         { &hf_smb_current_offset,
17987                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
17988                 NULL, 0, "Current offset in the file", HFILL }},
17989
17990         { &hf_smb_t2_alignment,
17991                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
17992                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
17993
17994         { &hf_smb_t2_stream_name_length,
17995                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
17996                 NULL, 0, "Length of stream name", HFILL }},
17997
17998         { &hf_smb_t2_stream_size,
17999                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
18000                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18001
18002         { &hf_smb_t2_stream_name,
18003                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
18004                 NULL, 0, "Name of the stream", HFILL }},
18005
18006         { &hf_smb_t2_compressed_file_size,
18007                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
18008                 NULL, 0, "Size of the compressed file", HFILL }},
18009
18010         { &hf_smb_t2_compressed_format,
18011                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
18012                 NULL, 0, "Compression algorithm used", HFILL }},
18013
18014         { &hf_smb_t2_compressed_unit_shift,
18015                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
18016                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18017
18018         { &hf_smb_t2_compressed_chunk_shift,
18019                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
18020                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18021
18022         { &hf_smb_t2_compressed_cluster_shift,
18023                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
18024                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18025
18026         { &hf_smb_t2_marked_for_deletion,
18027                 { "Marked for Deletion", "smb.marked_for_deletion", FT_BOOLEAN, BASE_NONE,
18028                 TFS(&tfs_marked_for_deletion), 0x0, "Marked for deletion?", HFILL }},
18029
18030         { &hf_smb_dfs_path_consumed,
18031                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
18032                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
18033
18034         { &hf_smb_dfs_num_referrals,
18035                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
18036                 NULL, 0, "Number of referrals in this pdu", HFILL }},
18037
18038         { &hf_smb_get_dfs_server_hold_storage,
18039                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
18040                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
18041
18042         { &hf_smb_get_dfs_fielding,
18043                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
18044                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
18045
18046         { &hf_smb_dfs_referral_version,
18047                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
18048                 NULL, 0, "Version of referral element", HFILL }},
18049
18050         { &hf_smb_dfs_referral_size,
18051                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
18052                 NULL, 0, "Size of referral element", HFILL }},
18053
18054         { &hf_smb_dfs_referral_server_type,
18055                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
18056                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
18057
18058         { &hf_smb_dfs_referral_flags_strip,
18059                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
18060                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
18061
18062         { &hf_smb_dfs_referral_node_offset,
18063                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
18064                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
18065
18066         { &hf_smb_dfs_referral_node,
18067                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
18068                 NULL, 0, "Name of entity to visit next", HFILL }},
18069
18070         { &hf_smb_dfs_referral_proximity,
18071                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
18072                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
18073
18074         { &hf_smb_dfs_referral_ttl,
18075                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
18076                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
18077
18078         { &hf_smb_dfs_referral_path_offset,
18079                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
18080                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
18081
18082         { &hf_smb_dfs_referral_path,
18083                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
18084                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
18085
18086         { &hf_smb_dfs_referral_alt_path_offset,
18087                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
18088                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
18089
18090         { &hf_smb_dfs_referral_alt_path,
18091                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
18092                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
18093
18094         { &hf_smb_end_of_search,
18095                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
18096                 NULL, 0, "Was last entry returned?", HFILL }},
18097
18098         { &hf_smb_last_name_offset,
18099                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
18100                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
18101
18102         { &hf_smb_fn_information_level,
18103                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
18104                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
18105
18106         { &hf_smb_monitor_handle,
18107                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
18108                 NULL, 0, "Handle for Find Notify operations", HFILL }},
18109
18110         { &hf_smb_change_count,
18111                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
18112                 NULL, 0, "Number of changes to wait for", HFILL }},
18113
18114         { &hf_smb_file_index,
18115                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
18116                 NULL, 0, "File index", HFILL }},
18117
18118         { &hf_smb_short_file_name,
18119                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
18120                 NULL, 0, "Short (8.3) File Name", HFILL }},
18121
18122         { &hf_smb_short_file_name_len,
18123                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
18124                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
18125
18126         { &hf_smb_fs_id,
18127                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
18128                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
18129
18130         { &hf_smb_sector_unit,
18131                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
18132                 NULL, 0, "Sectors per allocation unit", HFILL }},
18133
18134         { &hf_smb_fs_units,
18135                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
18136                 NULL, 0, "Total number of units on this filesystem", HFILL }},
18137
18138         { &hf_smb_fs_sector,
18139                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
18140                 NULL, 0, "Bytes per sector", HFILL }},
18141
18142         { &hf_smb_avail_units,
18143                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
18144                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
18145
18146         { &hf_smb_volume_serial_num,
18147                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
18148                 NULL, 0, "Volume serial number", HFILL }},
18149
18150         { &hf_smb_volume_label_len,
18151                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
18152                 NULL, 0, "Length of volume label", HFILL }},
18153
18154         { &hf_smb_volume_label,
18155                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
18156                 NULL, 0, "Volume label", HFILL }},
18157
18158         { &hf_smb_free_alloc_units64,
18159                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
18160                 NULL, 0, "Number of free allocation units", HFILL }},
18161
18162         { &hf_smb_caller_free_alloc_units64,
18163                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
18164                 NULL, 0, "Number of caller free allocation units", HFILL }},
18165
18166         { &hf_smb_actual_free_alloc_units64,
18167                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
18168                 NULL, 0, "Number of actual free allocation units", HFILL }},
18169
18170         { &hf_smb_soft_quota_limit,
18171                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
18172                 NULL, 0, "Soft Quota treshold", HFILL }},
18173
18174         { &hf_smb_hard_quota_limit,
18175                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
18176                 NULL, 0, "Hard Quota limit", HFILL }},
18177
18178         { &hf_smb_user_quota_used,
18179                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
18180                 NULL, 0, "How much Quota is used by this user", HFILL }},
18181
18182         { &hf_smb_max_name_len,
18183                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
18184                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
18185
18186         { &hf_smb_fs_name_len,
18187                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
18188                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
18189
18190         { &hf_smb_fs_name,
18191                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
18192                 NULL, 0, "Name of filesystem", HFILL }},
18193
18194         { &hf_smb_device_char_removable,
18195                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
18196                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
18197
18198         { &hf_smb_device_char_read_only,
18199                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
18200                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
18201
18202         { &hf_smb_device_char_floppy,
18203                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
18204                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
18205
18206         { &hf_smb_device_char_write_once,
18207                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
18208                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
18209
18210         { &hf_smb_device_char_remote,
18211                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
18212                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
18213
18214         { &hf_smb_device_char_mounted,
18215                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
18216                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
18217
18218         { &hf_smb_device_char_virtual,
18219                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
18220                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
18221
18222         { &hf_smb_fs_attr_css,
18223                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
18224                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
18225
18226         { &hf_smb_fs_attr_cpn,
18227                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
18228                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
18229
18230         { &hf_smb_fs_attr_pacls,
18231                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
18232                 TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
18233
18234         { &hf_smb_fs_attr_fc,
18235                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
18236                 TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
18237
18238         { &hf_smb_fs_attr_vq,
18239                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
18240                 TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
18241
18242         { &hf_smb_fs_attr_dim,
18243                 { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
18244                 TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
18245
18246         { &hf_smb_fs_attr_vic,
18247                 { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
18248                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
18249
18250         { &hf_smb_sec_desc_revision,
18251                 { "Revision", "smb.sec_desc.revision", FT_UINT8, BASE_DEC,
18252                 NULL, 0, "Version of NT Security Descriptor structure", HFILL }},
18253
18254         { &hf_smb_sid,
18255                 { "SID", "smb.sid", FT_STRING, BASE_DEC,
18256                 NULL, 0, "SID: Security Identifier", HFILL }},
18257
18258         { &hf_smb_sid_revision,
18259                 { "Revision", "smb.sid.revision", FT_UINT8, BASE_DEC,
18260                 NULL, 0, "Version of SID structure", HFILL }},
18261
18262         { &hf_smb_sid_num_auth,
18263                 { "Num Auth", "smb.sid.num_auth", FT_UINT8, BASE_DEC,
18264                 NULL, 0, "Number of authorities for this SID", HFILL }},
18265
18266         { &hf_smb_acl_revision,
18267                 { "Revision", "smb.acl.revision", FT_UINT16, BASE_DEC,
18268                 NULL, 0, "Version of NT ACL structure", HFILL }},
18269
18270         { &hf_smb_acl_size,
18271                 { "Size", "smb.acl.size", FT_UINT16, BASE_DEC,
18272                 NULL, 0, "Size of NT ACL structure", HFILL }},
18273
18274         { &hf_smb_acl_num_aces,
18275                 { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
18276                 NULL, 0, "Number of ACE structures for this ACL", HFILL }},
18277
18278         { &hf_smb_user_quota_offset,
18279                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
18280                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
18281
18282         { &hf_smb_ace_type,
18283                 { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
18284                 VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
18285
18286         { &hf_smb_pipe_write_len,
18287                 { "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
18288                 NULL, 0, "Number of bytes written to pipe", HFILL }},
18289
18290         { &hf_smb_ace_size,
18291                 { "Size", "smb.ace.size", FT_UINT16, BASE_DEC,
18292                 NULL, 0, "Size of this ACE", HFILL }},
18293
18294         { &hf_smb_ace_flags_object_inherit,
18295                 { "Object Inherit", "smb.ace.flags.object_inherit", FT_BOOLEAN, 8,
18296                 TFS(&tfs_ace_flags_object_inherit), 0x01, "Will subordinate files inherit this ACE?", HFILL }},
18297
18298         { &hf_smb_ace_flags_container_inherit,
18299                 { "Container Inherit", "smb.ace.flags.container_inherit", FT_BOOLEAN, 8,
18300                 TFS(&tfs_ace_flags_container_inherit), 0x02, "Will subordinate containers inherit this ACE?", HFILL }},
18301
18302         { &hf_smb_ace_flags_non_propagate_inherit,
18303                 { "Non-Propagate Inherit", "smb.ace.flags.non_propagate_inherit", FT_BOOLEAN, 8,
18304                 TFS(&tfs_ace_flags_non_propagate_inherit), 0x04, "Will subordinate object propagate this ACE further?", HFILL }},
18305
18306         { &hf_smb_ace_flags_inherit_only,
18307                 { "Inherit Only", "smb.ace.flags.inherit_only", FT_BOOLEAN, 8,
18308                 TFS(&tfs_ace_flags_inherit_only), 0x08, "Does this ACE apply to the current object?", HFILL }},
18309
18310         { &hf_smb_ace_flags_inherited_ace,
18311                 { "Inherited ACE", "smb.ace.flags.inherited_ace", FT_BOOLEAN, 8,
18312                 TFS(&tfs_ace_flags_inherited_ace), 0x10, "Was this ACE inherited from its parent object?", HFILL }},
18313
18314         { &hf_smb_ace_flags_successful_access,
18315                 { "Audit Successful Accesses", "smb.ace.flags.successful_access", FT_BOOLEAN, 8,
18316                 TFS(&tfs_ace_flags_successful_access), 0x40, "Should successful accesses be audited?", HFILL }},
18317
18318         { &hf_smb_ace_flags_failed_access,
18319                 { "Audit Failed Accesses", "smb.ace.flags.failed_access", FT_BOOLEAN, 8,
18320                 TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
18321
18322         { &hf_smb_sec_desc_type_owner_defaulted,
18323                 { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
18324                 TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
18325
18326         { &hf_smb_sec_desc_type_group_defaulted,
18327                 { "Group Defaulted", "smb.sec_desc.type.group_defaulted", FT_BOOLEAN, 16,
18328                 TFS(&tfs_sec_desc_type_group_defaulted), 0x0002, "Is Group Defaulted?", HFILL }},
18329
18330         { &hf_smb_sec_desc_type_dacl_present,
18331                 { "DACL Present", "smb.sec_desc.type.dacl_present", FT_BOOLEAN, 16,
18332                 TFS(&tfs_sec_desc_type_dacl_present), 0x0004, "Does this SecDesc have DACL present?", HFILL }},
18333
18334         { &hf_smb_sec_desc_type_dacl_defaulted,
18335                 { "DACL Defaulted", "smb.sec_desc.type.dacl_defaulted", FT_BOOLEAN, 16,
18336                 TFS(&tfs_sec_desc_type_dacl_defaulted), 0x0008, "Does this SecDesc have DACL Defaulted?", HFILL }},
18337
18338         { &hf_smb_sec_desc_type_sacl_present,
18339                 { "SACL Present", "smb.sec_desc.type.sacl_present", FT_BOOLEAN, 16,
18340                 TFS(&tfs_sec_desc_type_sacl_present), 0x0010, "Is the SACL present?", HFILL }},
18341
18342         { &hf_smb_sec_desc_type_sacl_defaulted,
18343                 { "SACL Defaulted", "smb.sec_desc.type.sacl_defaulted", FT_BOOLEAN, 16,
18344                 TFS(&tfs_sec_desc_type_sacl_defaulted), 0x0020, "Does this SecDesc have SACL Defaulted?", HFILL }},
18345
18346         { &hf_smb_sec_desc_type_dacl_auto_inherit_req,
18347                 { "DACL Auto Inherit Required", "smb.sec_desc.type.dacl_auto_inherit_req", FT_BOOLEAN, 16,
18348                 TFS(&tfs_sec_desc_type_dacl_auto_inherit_req), 0x0100, "Does this SecDesc have DACL Auto Inherit Required set?", HFILL }},
18349
18350         { &hf_smb_sec_desc_type_sacl_auto_inherit_req,
18351                 { "SACL Auto Inherit Required", "smb.sec_desc.type.sacl_auto_inherit_req", FT_BOOLEAN, 16,
18352                 TFS(&tfs_sec_desc_type_sacl_auto_inherit_req), 0x0200, "Does this SecDesc have SACL Auto Inherit Required set?", HFILL }},
18353
18354         { &hf_smb_sec_desc_type_dacl_auto_inherited,
18355                 { "DACL Auto Inherited", "smb.sec_desc.type.dacl_auto_inherited", FT_BOOLEAN, 16,
18356                 TFS(&tfs_sec_desc_type_dacl_auto_inherited), 0x0400, "Is this DACL auto inherited", HFILL }},
18357
18358         { &hf_smb_sec_desc_type_sacl_auto_inherited,
18359                 { "SACL Auto Inherited", "smb.sec_desc.type.sacl_auto_inherited", FT_BOOLEAN, 16,
18360                 TFS(&tfs_sec_desc_type_sacl_auto_inherited), 0x0800, "Is this SACL auto inherited", HFILL }},
18361
18362         { &hf_smb_sec_desc_type_dacl_protected,
18363                 { "DACL Protected", "smb.sec_desc.type.dacl_protected", FT_BOOLEAN, 16,
18364                 TFS(&tfs_sec_desc_type_dacl_protected), 0x1000, "Is the DACL structure protected?", HFILL }},
18365
18366         { &hf_smb_sec_desc_type_sacl_protected,
18367                 { "SACL Protected", "smb.sec_desc.type.sacl_protected", FT_BOOLEAN, 16,
18368                 TFS(&tfs_sec_desc_type_sacl_protected), 0x2000, "Is the SACL structure protected?", HFILL }},
18369
18370         { &hf_smb_sec_desc_type_self_relative,
18371                 { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
18372                 TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
18373
18374         { &hf_smb_quota_flags_deny_disk,
18375                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
18376                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
18377
18378         { &hf_smb_quota_flags_log_limit,
18379                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
18380                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
18381
18382         { &hf_smb_quota_flags_log_warning,
18383                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
18384                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
18385
18386         { &hf_smb_quota_flags_enabled,
18387                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
18388                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
18389
18390         { &hf_smb_segment_overlap,
18391                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18392                         "Fragment overlaps with other fragments", HFILL }},
18393
18394         { &hf_smb_segment_overlap_conflict,
18395                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18396                         "Overlapping fragments contained conflicting data", HFILL }},
18397
18398         { &hf_smb_segment_multiple_tails,
18399                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18400                         "Several tails were found when defragmenting the packet", HFILL }},
18401
18402         { &hf_smb_segment_too_long_fragment,
18403                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18404                         "Fragment contained data past end of packet", HFILL }},
18405
18406         { &hf_smb_segment_error,
18407                 { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18408                         "Defragmentation error due to illegal fragments", HFILL }},
18409
18410         { &hf_smb_segment,
18411                 { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18412                         "SMB Segment", HFILL }},
18413
18414         { &hf_smb_segments,
18415                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
18416                         "SMB Segments", HFILL }},
18417
18418                 /* Access masks */
18419
18420                 { &hf_smb_access_mask,
18421                   { "Access required", "smb.access_mask",
18422                     FT_UINT32, BASE_HEX, NULL, 0x0, "Access mask",
18423                     HFILL }},
18424                 { &hf_access_generic_read,
18425                   { "Generic read", "nt.access_mask.generic_read",
18426                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18427                     GENERIC_READ_ACCESS, "Generic read", HFILL }},
18428
18429                 { &hf_access_generic_write,
18430                   { "Generic write", "nt.access_mask.generic_write",
18431                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18432                     GENERIC_WRITE_ACCESS, "Generic write", HFILL }},
18433
18434                 { &hf_access_generic_execute,
18435                   { "Generic execute", "nt.access_mask.generic_execute",
18436                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18437                     GENERIC_EXECUTE_ACCESS, "Generic execute", HFILL }},
18438
18439                 { &hf_access_generic_all,
18440                   { "Generic all", "nt.access_mask.generic_all",
18441                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18442                     GENERIC_ALL_ACCESS, "Generic all", HFILL }},
18443
18444                 { &hf_access_maximum_allowed,
18445                   { "Maximum allowed", "nt.access_mask.maximum_allowed",
18446                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18447                     MAXIMUM_ALLOWED_ACCESS, "Maximum allowed", HFILL }},
18448
18449                 { &hf_access_sacl,
18450                   { "Access SACL", "nt.access_mask.access_sacl",
18451                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18452                     ACCESS_SACL_ACCESS, "Access SACL", HFILL }},
18453
18454                 { &hf_access_standard_read_control,
18455                   { "Read control", "nt.access_mask.read_control",
18456                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18457                     READ_CONTROL_ACCESS, "Read control", HFILL }},
18458
18459                 { &hf_access_standard_delete,
18460                   { "Delete", "nt.access_mask.delete",
18461                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18462                     DELETE_ACCESS, "Delete", HFILL }},
18463
18464                 { &hf_access_standard_synchronise,
18465                   { "Synchronise", "nt.access_mask.synchronise",
18466                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18467                     SYNCHRONIZE_ACCESS, "Synchronise", HFILL }},
18468
18469                 { &hf_access_standard_write_dac,
18470                   { "Write DAC", "nt.access_mask.write_dac",
18471                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18472                     WRITE_DAC_ACCESS, "Write DAC", HFILL }},
18473
18474                 { &hf_access_standard_write_owner,
18475                   { "Write owner", "nt.access_mask.write_owner",
18476                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18477                     WRITE_OWNER_ACCESS, "Write owner", HFILL }},
18478
18479                 { &hf_access_specific_15,
18480                   { "Specific access, bit 15", "nt.access_mask.specific_15",
18481                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18482                     0x8000, "Specific access, bit 15", HFILL }},
18483
18484                 { &hf_access_specific_14,
18485                   { "Specific access, bit 14", "nt.access_mask.specific_14",
18486                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18487                     0x4000, "Specific access, bit 14", HFILL }},
18488
18489                 { &hf_access_specific_13,
18490                   { "Specific access, bit 13", "nt.access_mask.specific_13",
18491                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18492                     0x2000, "Specific access, bit 13", HFILL }},
18493
18494                 { &hf_access_specific_12,
18495                   { "Specific access, bit 12", "nt.access_mask.specific_12",
18496                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18497                     0x1000, "Specific access, bit 12", HFILL }},
18498
18499                 { &hf_access_specific_11,
18500                   { "Specific access, bit 11", "nt.access_mask.specific_11",
18501                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18502                     0x0800, "Specific access, bit 11", HFILL }},
18503
18504                 { &hf_access_specific_10,
18505                   { "Specific access, bit 10", "nt.access_mask.specific_10",
18506                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18507                     0x0400, "Specific access, bit 10", HFILL }},
18508
18509                 { &hf_access_specific_9,
18510                   { "Specific access, bit 9", "nt.access_mask.specific_9",
18511                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18512                     0x0200, "Specific access, bit 9", HFILL }},
18513
18514                 { &hf_access_specific_8,
18515                   { "Specific access, bit 8", "nt.access_mask.specific_8",
18516                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18517                     0x0100, "Specific access, bit 8", HFILL }},
18518
18519                 { &hf_access_specific_7,
18520                   { "Specific access, bit 7", "nt.access_mask.specific_7",
18521                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18522                     0x0080, "Specific access, bit 7", HFILL }},
18523
18524                 { &hf_access_specific_6,
18525                   { "Specific access, bit 6", "nt.access_mask.specific_6",
18526                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18527                     0x0040, "Specific access, bit 6", HFILL }},
18528
18529                 { &hf_access_specific_5,
18530                   { "Specific access, bit 5", "nt.access_mask.specific_5",
18531                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18532                     0x0020, "Specific access, bit 5", HFILL }},
18533
18534                 { &hf_access_specific_4,
18535                   { "Specific access, bit 4", "nt.access_mask.specific_4",
18536                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18537                     0x0010, "Specific access, bit 4", HFILL }},
18538
18539                 { &hf_access_specific_3,
18540                   { "Specific access, bit 3", "nt.access_mask.specific_3",
18541                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18542                     0x0008, "Specific access, bit 3", HFILL }},
18543
18544                 { &hf_access_specific_2,
18545                   { "Specific access, bit 2", "nt.access_mask.specific_2",
18546                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18547                     0x0004, "Specific access, bit 2", HFILL }},
18548
18549                 { &hf_access_specific_1,
18550                   { "Specific access, bit 1", "nt.access_mask.specific_1",
18551                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18552                     0x0002, "Specific access, bit 1", HFILL }},
18553
18554                 { &hf_access_specific_0,
18555                   { "Specific access, bit 0", "nt.access_mask.specific_0",
18556                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
18557                     0x0001, "Specific access, bit 0", HFILL }}
18558         };
18559
18560         static gint *ett[] = {
18561                 &ett_smb,
18562                 &ett_smb_hdr,
18563                 &ett_smb_command,
18564                 &ett_smb_fileattributes,
18565                 &ett_smb_capabilities,
18566                 &ett_smb_aflags,
18567                 &ett_smb_dialect,
18568                 &ett_smb_dialects,
18569                 &ett_smb_mode,
18570                 &ett_smb_rawmode,
18571                 &ett_smb_flags,
18572                 &ett_smb_flags2,
18573                 &ett_smb_desiredaccess,
18574                 &ett_smb_search,
18575                 &ett_smb_file,
18576                 &ett_smb_openfunction,
18577                 &ett_smb_filetype,
18578                 &ett_smb_openaction,
18579                 &ett_smb_writemode,
18580                 &ett_smb_lock_type,
18581                 &ett_smb_ssetupandxaction,
18582                 &ett_smb_optionsup,
18583                 &ett_smb_time_date,
18584                 &ett_smb_move_copy_flags,
18585                 &ett_smb_file_attributes,
18586                 &ett_smb_search_resume_key,
18587                 &ett_smb_search_dir_info,
18588                 &ett_smb_unlocks,
18589                 &ett_smb_unlock,
18590                 &ett_smb_locks,
18591                 &ett_smb_lock,
18592                 &ett_smb_open_flags,
18593                 &ett_smb_ipc_state,
18594                 &ett_smb_open_action,
18595                 &ett_smb_setup_action,
18596                 &ett_smb_connect_flags,
18597                 &ett_smb_connect_support_bits,
18598                 &ett_smb_nt_access_mask,
18599                 &ett_smb_nt_create_bits,
18600                 &ett_smb_nt_create_options,
18601                 &ett_smb_nt_share_access,
18602                 &ett_smb_nt_security_flags,
18603                 &ett_smb_nt_trans_setup,
18604                 &ett_smb_nt_trans_data,
18605                 &ett_smb_nt_trans_param,
18606                 &ett_smb_nt_notify_completion_filter,
18607                 &ett_smb_nt_ioctl_flags,
18608                 &ett_smb_security_information_mask,
18609                 &ett_smb_print_queue_entry,
18610                 &ett_smb_transaction_flags,
18611                 &ett_smb_transaction_params,
18612                 &ett_smb_find_first2_flags,
18613 #if 0
18614                 &ett_smb_ioflag,
18615 #endif
18616                 &ett_smb_transaction_data,
18617                 &ett_smb_stream_info,
18618                 &ett_smb_dfs_referrals,
18619                 &ett_smb_dfs_referral,
18620                 &ett_smb_dfs_referral_flags,
18621                 &ett_smb_get_dfs_flags,
18622                 &ett_smb_ff2_data,
18623                 &ett_smb_device_characteristics,
18624                 &ett_smb_fs_attributes,
18625                 &ett_smb_segments,
18626                 &ett_smb_segment,
18627                 &ett_smb_sec_desc,
18628                 &ett_smb_sid,
18629                 &ett_smb_acl,
18630                 &ett_smb_ace,
18631                 &ett_smb_ace_flags,
18632                 &ett_smb_sec_desc_type,
18633                 &ett_smb_quotaflags,
18634                 &ett_smb_secblob,
18635                 &ett_smb_mac_support_flags,
18636                 &ett_nt_access_mask,
18637                 &ett_nt_access_mask_generic,
18638                 &ett_nt_access_mask_standard,
18639                 &ett_nt_access_mask_specific,
18640                 &ett_smb_unicode_password,
18641                 &ett_smb_ea
18642         };
18643         module_t *smb_module;
18644
18645         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
18646             "SMB", "smb");
18647         proto_register_subtree_array(ett, array_length(ett));
18648         proto_register_field_array(proto_smb, hf, array_length(hf));
18649
18650         register_smb_common(proto_smb);
18651
18652         register_init_routine(&smb_init_protocol);
18653         smb_module = prefs_register_protocol(proto_smb, NULL);
18654         prefs_register_bool_preference(smb_module, "trans_reassembly",
18655                 "Reassemble SMB Transaction payload",
18656                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
18657                 &smb_trans_reassembly);
18658         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
18659                 "Reassemble DCERPC over SMB",
18660                 "Whether the dissector should reassemble DCERPC over SMB commands",
18661                 &smb_dcerpc_reassembly);
18662         prefs_register_bool_preference(smb_module, "sid_name_snooping",
18663                 "Snoop SID to Name mappings",
18664                 "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
18665                 &sid_name_snooping);
18666
18667         register_init_routine(smb_trans_reassembly_init);
18668         smb_tap = register_tap("smb");
18669 }
18670
18671 void
18672 proto_reg_handoff_smb(void)
18673 {
18674         dissector_handle_t smb_handle;
18675
18676         gssapi_handle = find_dissector("gssapi");
18677         ntlmssp_handle = find_dissector("ntlmssp");
18678
18679         heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
18680         heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
18681         heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
18682         smb_handle = create_dissector_handle(dissect_smb, proto_smb);
18683         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
18684         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
18685         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER,
18686             smb_handle);
18687 }