Removed trailing whitespaces from .h and .c files using the
[obnox/wireshark/wip.git] / packet-smb.c
1 /* packet-smb.c
2  * Routines for smb packet dissection
3  * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
4  * 2001  Rewrite by Ronnie Sahlberg and Guy Harris
5  *
6  * $Id: packet-smb.c,v 1.284 2002/08/28 21:00:31 jmayer 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
47 #include "packet-smb-common.h"
48 #include "packet-smb-mailslot.h"
49 #include "packet-smb-pipe.h"
50
51 /*
52  * Various specifications and documents about SMB can be found in
53  *
54  *      ftp://ftp.microsoft.com/developr/drg/CIFS/
55  *
56  * and a CIFS specification from the Storage Networking Industry Association
57  * can be found on a link from the page at
58  *
59  *      http://www.snia.org/English/Collaterals/Work_Group_Docs/NAS/CIFS/CIFS_Technical_Reference.pdf
60  *
61  * (it supercedes the document at
62  *
63  *      ftp://ftp.microsoft.com/developr/drg/CIFS/draft-leach-cifs-v1-spec-01.txt
64  *
65  * ).
66  *
67  * There are also some Open Group publications documenting CIFS for sale;
68  * catalog entries for them are at:
69  *
70  *      http://www.opengroup.org/products/publications/catalog/c209.htm
71  *
72  *      http://www.opengroup.org/products/publications/catalog/c195.htm
73  *
74  * The document "NT LAN Manager SMB File Sharing Protocol Extensions"
75  * can be found at
76  *
77  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
78  *
79  * (or, presumably a similar path under the Samba mirrors).  As the
80  * ".doc" indicates, it's a Word document.  Some of the specs from the
81  * Microsoft FTP site can be found in the
82  *
83  *      http://www.samba.org/samba/ftp/specs/
84  *
85  * directory as well.
86  *
87  * Beware - these specs may have errors.
88  */
89 static int proto_smb = -1;
90 static int hf_smb_cmd = -1;
91 static int hf_smb_pid = -1;
92 static int hf_smb_tid = -1;
93 static int hf_smb_uid = -1;
94 static int hf_smb_mid = -1;
95 static int hf_smb_response_to = -1;
96 static int hf_smb_time = -1;
97 static int hf_smb_response_in = -1;
98 static int hf_smb_continuation_to = -1;
99 static int hf_smb_nt_status = -1;
100 static int hf_smb_error_class = -1;
101 static int hf_smb_error_code = -1;
102 static int hf_smb_reserved = -1;
103 static int hf_smb_flags_lock = -1;
104 static int hf_smb_flags_receive_buffer = -1;
105 static int hf_smb_flags_caseless = -1;
106 static int hf_smb_flags_canon = -1;
107 static int hf_smb_flags_oplock = -1;
108 static int hf_smb_flags_notify = -1;
109 static int hf_smb_flags_response = -1;
110 static int hf_smb_flags2_long_names_allowed = -1;
111 static int hf_smb_flags2_ea = -1;
112 static int hf_smb_flags2_sec_sig = -1;
113 static int hf_smb_flags2_long_names_used = -1;
114 static int hf_smb_flags2_esn = -1;
115 static int hf_smb_flags2_dfs = -1;
116 static int hf_smb_flags2_roe = -1;
117 static int hf_smb_flags2_nt_error = -1;
118 static int hf_smb_flags2_string = -1;
119 static int hf_smb_word_count = -1;
120 static int hf_smb_byte_count = -1;
121 static int hf_smb_buffer_format = -1;
122 static int hf_smb_dialect_name = -1;
123 static int hf_smb_dialect_index = -1;
124 static int hf_smb_max_trans_buf_size = -1;
125 static int hf_smb_max_mpx_count = -1;
126 static int hf_smb_max_vcs_num = -1;
127 static int hf_smb_session_key = -1;
128 static int hf_smb_server_timezone = -1;
129 static int hf_smb_encryption_key_length = -1;
130 static int hf_smb_encryption_key = -1;
131 static int hf_smb_primary_domain = -1;
132 static int hf_smb_server = -1;
133 static int hf_smb_max_raw_buf_size = -1;
134 static int hf_smb_server_guid = -1;
135 static int hf_smb_security_blob_len = -1;
136 static int hf_smb_security_blob = -1;
137 static int hf_smb_sm_mode16 = -1;
138 static int hf_smb_sm_password16 = -1;
139 static int hf_smb_sm_mode = -1;
140 static int hf_smb_sm_password = -1;
141 static int hf_smb_sm_signatures = -1;
142 static int hf_smb_sm_sig_required = -1;
143 static int hf_smb_rm_read = -1;
144 static int hf_smb_rm_write = -1;
145 static int hf_smb_server_date_time = -1;
146 static int hf_smb_server_smb_date = -1;
147 static int hf_smb_server_smb_time = -1;
148 static int hf_smb_server_cap_raw_mode = -1;
149 static int hf_smb_server_cap_mpx_mode = -1;
150 static int hf_smb_server_cap_unicode = -1;
151 static int hf_smb_server_cap_large_files = -1;
152 static int hf_smb_server_cap_nt_smbs = -1;
153 static int hf_smb_server_cap_rpc_remote_apis = -1;
154 static int hf_smb_server_cap_nt_status = -1;
155 static int hf_smb_server_cap_level_ii_oplocks = -1;
156 static int hf_smb_server_cap_lock_and_read = -1;
157 static int hf_smb_server_cap_nt_find = -1;
158 static int hf_smb_server_cap_dfs = -1;
159 static int hf_smb_server_cap_infolevel_passthru = -1;
160 static int hf_smb_server_cap_large_readx = -1;
161 static int hf_smb_server_cap_large_writex = -1;
162 static int hf_smb_server_cap_unix = -1;
163 static int hf_smb_server_cap_reserved = -1;
164 static int hf_smb_server_cap_bulk_transfer = -1;
165 static int hf_smb_server_cap_compressed_data = -1;
166 static int hf_smb_server_cap_extended_security = -1;
167 static int hf_smb_system_time = -1;
168 static int hf_smb_unknown = -1;
169 static int hf_smb_dir_name = -1;
170 static int hf_smb_echo_count = -1;
171 static int hf_smb_echo_data = -1;
172 static int hf_smb_echo_seq_num = -1;
173 static int hf_smb_max_buf_size = -1;
174 static int hf_smb_password = -1;
175 static int hf_smb_password_len = -1;
176 static int hf_smb_ansi_password = -1;
177 static int hf_smb_ansi_password_len = -1;
178 static int hf_smb_unicode_password = -1;
179 static int hf_smb_unicode_password_len = -1;
180 static int hf_smb_path = -1;
181 static int hf_smb_service = -1;
182 static int hf_smb_move_flags_file = -1;
183 static int hf_smb_move_flags_dir = -1;
184 static int hf_smb_move_flags_verify = -1;
185 static int hf_smb_files_moved = -1;
186 static int hf_smb_copy_flags_file = -1;
187 static int hf_smb_copy_flags_dir = -1;
188 static int hf_smb_copy_flags_dest_mode = -1;
189 static int hf_smb_copy_flags_source_mode = -1;
190 static int hf_smb_copy_flags_verify = -1;
191 static int hf_smb_copy_flags_tree_copy = -1;
192 static int hf_smb_copy_flags_ea_action = -1;
193 static int hf_smb_count = -1;
194 static int hf_smb_file_name = -1;
195 static int hf_smb_open_function_open = -1;
196 static int hf_smb_open_function_create = -1;
197 static int hf_smb_fid = -1;
198 static int hf_smb_file_attr_read_only_16bit = -1;
199 static int hf_smb_file_attr_read_only_8bit = -1;
200 static int hf_smb_file_attr_hidden_16bit = -1;
201 static int hf_smb_file_attr_hidden_8bit = -1;
202 static int hf_smb_file_attr_system_16bit = -1;
203 static int hf_smb_file_attr_system_8bit = -1;
204 static int hf_smb_file_attr_volume_16bit = -1;
205 static int hf_smb_file_attr_volume_8bit = -1;
206 static int hf_smb_file_attr_directory_16bit = -1;
207 static int hf_smb_file_attr_directory_8bit = -1;
208 static int hf_smb_file_attr_archive_16bit = -1;
209 static int hf_smb_file_attr_archive_8bit = -1;
210 static int hf_smb_file_attr_device = -1;
211 static int hf_smb_file_attr_normal = -1;
212 static int hf_smb_file_attr_temporary = -1;
213 static int hf_smb_file_attr_sparse = -1;
214 static int hf_smb_file_attr_reparse = -1;
215 static int hf_smb_file_attr_compressed = -1;
216 static int hf_smb_file_attr_offline = -1;
217 static int hf_smb_file_attr_not_content_indexed = -1;
218 static int hf_smb_file_attr_encrypted = -1;
219 static int hf_smb_file_size = -1;
220 static int hf_smb_search_attribute_read_only = -1;
221 static int hf_smb_search_attribute_hidden = -1;
222 static int hf_smb_search_attribute_system = -1;
223 static int hf_smb_search_attribute_volume = -1;
224 static int hf_smb_search_attribute_directory = -1;
225 static int hf_smb_search_attribute_archive = -1;
226 static int hf_smb_access_mode = -1;
227 static int hf_smb_access_sharing = -1;
228 static int hf_smb_access_locality = -1;
229 static int hf_smb_access_caching = -1;
230 static int hf_smb_access_writetru = -1;
231 static int hf_smb_create_time = -1;
232 static int hf_smb_modify_time = -1;
233 static int hf_smb_backup_time = -1;
234 static int hf_smb_mac_alloc_block_count = -1;
235 static int hf_smb_mac_alloc_block_size = -1;
236 static int hf_smb_mac_free_block_count = -1;
237 static int hf_smb_mac_fndrinfo = -1;
238 static int hf_smb_mac_root_file_count = -1;
239 static int hf_smb_mac_root_dir_count = -1;
240 static int hf_smb_mac_file_count = -1;
241 static int hf_smb_mac_dir_count = -1;
242 static int hf_smb_mac_support_flags = -1;
243 static int hf_smb_mac_sup_access_ctrl = -1;
244 static int hf_smb_mac_sup_getset_comments = -1;
245 static int hf_smb_mac_sup_desktopdb_calls = -1;
246 static int hf_smb_mac_sup_unique_ids = -1;
247 static int hf_smb_mac_sup_streams = -1;
248 static int hf_smb_create_dos_date = -1;
249 static int hf_smb_create_dos_time = -1;
250 static int hf_smb_last_write_time = -1;
251 static int hf_smb_last_write_dos_date = -1;
252 static int hf_smb_last_write_dos_time = -1;
253 static int hf_smb_access_time = -1;
254 static int hf_smb_access_dos_date = -1;
255 static int hf_smb_access_dos_time = -1;
256 static int hf_smb_old_file_name = -1;
257 static int hf_smb_offset = -1;
258 static int hf_smb_remaining = -1;
259 static int hf_smb_padding = -1;
260 static int hf_smb_file_data = -1;
261 static int hf_smb_total_data_len = -1;
262 static int hf_smb_data_len = -1;
263 static int hf_smb_seek_mode = -1;
264 static int hf_smb_data_size = -1;
265 static int hf_smb_alloc_size = -1;
266 static int hf_smb_alloc_size64 = -1;
267 static int hf_smb_max_count = -1;
268 static int hf_smb_min_count = -1;
269 static int hf_smb_timeout = -1;
270 static int hf_smb_high_offset = -1;
271 static int hf_smb_units = -1;
272 static int hf_smb_bpu = -1;
273 static int hf_smb_blocksize = -1;
274 static int hf_smb_freeunits = -1;
275 static int hf_smb_data_offset = -1;
276 static int hf_smb_dcm = -1;
277 static int hf_smb_request_mask = -1;
278 static int hf_smb_response_mask = -1;
279 static int hf_smb_sid = -1;
280 static int hf_smb_write_mode_write_through = -1;
281 static int hf_smb_write_mode_return_remaining = -1;
282 static int hf_smb_write_mode_raw = -1;
283 static int hf_smb_write_mode_message_start = -1;
284 static int hf_smb_write_mode_connectionless = -1;
285 static int hf_smb_resume_key_len = -1;
286 static int hf_smb_resume_find_id = -1;
287 static int hf_smb_resume_server_cookie = -1;
288 static int hf_smb_resume_client_cookie = -1;
289 static int hf_smb_andxoffset = -1;
290 static int hf_smb_lock_type_large = -1;
291 static int hf_smb_lock_type_cancel = -1;
292 static int hf_smb_lock_type_change = -1;
293 static int hf_smb_lock_type_oplock = -1;
294 static int hf_smb_lock_type_shared = -1;
295 static int hf_smb_locking_ol = -1;
296 static int hf_smb_number_of_locks = -1;
297 static int hf_smb_number_of_unlocks = -1;
298 static int hf_smb_lock_long_offset = -1;
299 static int hf_smb_lock_long_length = -1;
300 static int hf_smb_file_type = -1;
301 static int hf_smb_ipc_state_nonblocking = -1;
302 static int hf_smb_ipc_state_endpoint = -1;
303 static int hf_smb_ipc_state_pipe_type = -1;
304 static int hf_smb_ipc_state_read_mode = -1;
305 static int hf_smb_ipc_state_icount = -1;
306 static int hf_smb_server_fid = -1;
307 static int hf_smb_open_flags_add_info = -1;
308 static int hf_smb_open_flags_ex_oplock = -1;
309 static int hf_smb_open_flags_batch_oplock = -1;
310 static int hf_smb_open_flags_ealen = -1;
311 static int hf_smb_open_action_open = -1;
312 static int hf_smb_open_action_lock = -1;
313 static int hf_smb_vc_num = -1;
314 static int hf_smb_account = -1;
315 static int hf_smb_os = -1;
316 static int hf_smb_lanman = -1;
317 static int hf_smb_setup_action_guest = -1;
318 static int hf_smb_fs = -1;
319 static int hf_smb_connect_flags_dtid = -1;
320 static int hf_smb_connect_support_search = -1;
321 static int hf_smb_connect_support_in_dfs = -1;
322 static int hf_smb_max_setup_count = -1;
323 static int hf_smb_total_param_count = -1;
324 static int hf_smb_total_data_count = -1;
325 static int hf_smb_max_param_count = -1;
326 static int hf_smb_max_data_count = -1;
327 static int hf_smb_param_disp16 = -1;
328 static int hf_smb_param_count16 = -1;
329 static int hf_smb_param_offset16 = -1;
330 static int hf_smb_param_disp32 = -1;
331 static int hf_smb_param_count32 = -1;
332 static int hf_smb_param_offset32 = -1;
333 static int hf_smb_data_disp16 = -1;
334 static int hf_smb_data_count16 = -1;
335 static int hf_smb_data_offset16 = -1;
336 static int hf_smb_data_disp32 = -1;
337 static int hf_smb_data_count32 = -1;
338 static int hf_smb_data_offset32 = -1;
339 static int hf_smb_setup_count = -1;
340 static int hf_smb_nt_trans_subcmd = -1;
341 static int hf_smb_nt_ioctl_function_code = -1;
342 static int hf_smb_nt_ioctl_isfsctl = -1;
343 static int hf_smb_nt_ioctl_flags_root_handle = -1;
344 static int hf_smb_nt_ioctl_data = -1;
345 #ifdef SMB_UNUSED_HANDLES
346 static int hf_smb_nt_security_information = -1;
347 #endif
348 static int hf_smb_nt_notify_action = -1;
349 static int hf_smb_nt_notify_watch_tree = -1;
350 static int hf_smb_nt_notify_stream_write = -1;
351 static int hf_smb_nt_notify_stream_size = -1;
352 static int hf_smb_nt_notify_stream_name = -1;
353 static int hf_smb_nt_notify_security = -1;
354 static int hf_smb_nt_notify_ea = -1;
355 static int hf_smb_nt_notify_creation = -1;
356 static int hf_smb_nt_notify_last_access = -1;
357 static int hf_smb_nt_notify_last_write = -1;
358 static int hf_smb_nt_notify_size = -1;
359 static int hf_smb_nt_notify_attributes = -1;
360 static int hf_smb_nt_notify_dir_name = -1;
361 static int hf_smb_nt_notify_file_name = -1;
362 static int hf_smb_root_dir_fid = -1;
363 static int hf_smb_nt_create_disposition = -1;
364 static int hf_smb_sd_length = -1;
365 static int hf_smb_ea_length = -1;
366 static int hf_smb_file_name_len = -1;
367 static int hf_smb_nt_impersonation_level = -1;
368 static int hf_smb_nt_security_flags_context_tracking = -1;
369 static int hf_smb_nt_security_flags_effective_only = -1;
370 static int hf_smb_nt_access_mask_generic_read = -1;
371 static int hf_smb_nt_access_mask_generic_write = -1;
372 static int hf_smb_nt_access_mask_generic_execute = -1;
373 static int hf_smb_nt_access_mask_generic_all = -1;
374 static int hf_smb_nt_access_mask_maximum_allowed = -1;
375 static int hf_smb_nt_access_mask_system_security = -1;
376 static int hf_smb_nt_access_mask_synchronize = -1;
377 static int hf_smb_nt_access_mask_write_owner = -1;
378 static int hf_smb_nt_access_mask_write_dac = -1;
379 static int hf_smb_nt_access_mask_read_control = -1;
380 static int hf_smb_nt_access_mask_delete = -1;
381 static int hf_smb_nt_access_mask_write_attributes = -1;
382 static int hf_smb_nt_access_mask_read_attributes = -1;
383 static int hf_smb_nt_access_mask_delete_child = -1;
384 static int hf_smb_nt_access_mask_execute = -1;
385 static int hf_smb_nt_access_mask_write_ea = -1;
386 static int hf_smb_nt_access_mask_read_ea = -1;
387 static int hf_smb_nt_access_mask_append = -1;
388 static int hf_smb_nt_access_mask_write = -1;
389 static int hf_smb_nt_access_mask_read = -1;
390 static int hf_smb_nt_create_bits_oplock = -1;
391 static int hf_smb_nt_create_bits_boplock = -1;
392 static int hf_smb_nt_create_bits_dir = -1;
393 static int hf_smb_nt_create_options_directory_file = -1;
394 static int hf_smb_nt_create_options_write_through = -1;
395 static int hf_smb_nt_create_options_sequential_only = -1;
396 static int hf_smb_nt_create_options_sync_io_alert = -1;
397 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
398 static int hf_smb_nt_create_options_non_directory_file = -1;
399 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
400 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
401 static int hf_smb_nt_create_options_random_access = -1;
402 static int hf_smb_nt_create_options_delete_on_close = -1;
403 static int hf_smb_nt_share_access_read = -1;
404 static int hf_smb_nt_share_access_write = -1;
405 static int hf_smb_nt_share_access_delete = -1;
406 static int hf_smb_file_eattr_read_only = -1;
407 static int hf_smb_file_eattr_hidden = -1;
408 static int hf_smb_file_eattr_system = -1;
409 static int hf_smb_file_eattr_volume = -1;
410 static int hf_smb_file_eattr_directory = -1;
411 static int hf_smb_file_eattr_archive = -1;
412 static int hf_smb_file_eattr_device = -1;
413 static int hf_smb_file_eattr_normal = -1;
414 static int hf_smb_file_eattr_temporary = -1;
415 static int hf_smb_file_eattr_sparse = -1;
416 static int hf_smb_file_eattr_reparse = -1;
417 static int hf_smb_file_eattr_compressed = -1;
418 static int hf_smb_file_eattr_offline = -1;
419 static int hf_smb_file_eattr_not_content_indexed = -1;
420 static int hf_smb_file_eattr_encrypted = -1;
421 static int hf_smb_file_eattr_write_through = -1;
422 static int hf_smb_file_eattr_no_buffering = -1;
423 static int hf_smb_file_eattr_random_access = -1;
424 static int hf_smb_file_eattr_sequential_scan = -1;
425 static int hf_smb_file_eattr_delete_on_close = -1;
426 static int hf_smb_file_eattr_backup_semantics = -1;
427 static int hf_smb_file_eattr_posix_semantics = -1;
428 static int hf_smb_sec_desc_len = -1;
429 static int hf_smb_sec_desc_revision = -1;
430 static int hf_smb_sec_desc_type_owner_defaulted = -1;
431 static int hf_smb_sec_desc_type_group_defaulted = -1;
432 static int hf_smb_sec_desc_type_dacl_present = -1;
433 static int hf_smb_sec_desc_type_dacl_defaulted = -1;
434 static int hf_smb_sec_desc_type_sacl_present = -1;
435 static int hf_smb_sec_desc_type_sacl_defaulted = -1;
436 static int hf_smb_sec_desc_type_dacl_auto_inherit_req = -1;
437 static int hf_smb_sec_desc_type_sacl_auto_inherit_req = -1;
438 static int hf_smb_sec_desc_type_dacl_auto_inherited = -1;
439 static int hf_smb_sec_desc_type_sacl_auto_inherited = -1;
440 static int hf_smb_sec_desc_type_dacl_protected = -1;
441 static int hf_smb_sec_desc_type_sacl_protected = -1;
442 static int hf_smb_sec_desc_type_self_relative = -1;
443 static int hf_smb_sid_revision = -1;
444 static int hf_smb_sid_num_auth = -1;
445 static int hf_smb_acl_revision = -1;
446 static int hf_smb_acl_size = -1;
447 static int hf_smb_acl_num_aces = -1;
448 static int hf_smb_ace_type = -1;
449 static int hf_smb_ace_size = -1;
450 static int hf_smb_ace_flags_object_inherit = -1;
451 static int hf_smb_ace_flags_container_inherit = -1;
452 static int hf_smb_ace_flags_non_propagate_inherit = -1;
453 static int hf_smb_ace_flags_inherit_only = -1;
454 static int hf_smb_ace_flags_inherited_ace = -1;
455 static int hf_smb_ace_flags_successful_access = -1;
456 static int hf_smb_ace_flags_failed_access = -1;
457 static int hf_smb_nt_qsd_owner = -1;
458 static int hf_smb_nt_qsd_group = -1;
459 static int hf_smb_nt_qsd_dacl = -1;
460 static int hf_smb_nt_qsd_sacl = -1;
461 static int hf_smb_extended_attributes = -1;
462 static int hf_smb_oplock_level = -1;
463 static int hf_smb_create_action = -1;
464 static int hf_smb_file_id = -1;
465 static int hf_smb_ea_error_offset = -1;
466 static int hf_smb_end_of_file = -1;
467 static int hf_smb_device_type = -1;
468 static int hf_smb_is_directory = -1;
469 static int hf_smb_next_entry_offset = -1;
470 static int hf_smb_change_time = -1;
471 static int hf_smb_setup_len = -1;
472 static int hf_smb_print_mode = -1;
473 static int hf_smb_print_identifier = -1;
474 static int hf_smb_restart_index = -1;
475 static int hf_smb_print_queue_date = -1;
476 static int hf_smb_print_queue_dos_date = -1;
477 static int hf_smb_print_queue_dos_time = -1;
478 static int hf_smb_print_status = -1;
479 static int hf_smb_print_spool_file_number = -1;
480 static int hf_smb_print_spool_file_size = -1;
481 static int hf_smb_print_spool_file_name = -1;
482 static int hf_smb_start_index = -1;
483 static int hf_smb_originator_name = -1;
484 static int hf_smb_destination_name = -1;
485 static int hf_smb_message_len = -1;
486 static int hf_smb_message = -1;
487 static int hf_smb_mgid = -1;
488 static int hf_smb_forwarded_name = -1;
489 static int hf_smb_machine_name = -1;
490 static int hf_smb_cancel_to = -1;
491 static int hf_smb_trans2_subcmd = -1;
492 static int hf_smb_trans_name = -1;
493 static int hf_smb_transaction_flags_dtid = -1;
494 static int hf_smb_transaction_flags_owt = -1;
495 static int hf_smb_search_count = -1;
496 static int hf_smb_search_pattern = -1;
497 static int hf_smb_ff2_backup = -1;
498 static int hf_smb_ff2_continue = -1;
499 static int hf_smb_ff2_resume = -1;
500 static int hf_smb_ff2_close_eos = -1;
501 static int hf_smb_ff2_close = -1;
502 static int hf_smb_ff2_information_level = -1;
503 static int hf_smb_qpi_loi = -1;
504 #if 0
505 static int hf_smb_sfi_writetru = -1;
506 static int hf_smb_sfi_caching = -1;
507 #endif
508 static int hf_smb_storage_type = -1;
509 static int hf_smb_resume = -1;
510 static int hf_smb_max_referral_level = -1;
511 static int hf_smb_qfsi_information_level = -1;
512 static int hf_smb_ea_size = -1;
513 static int hf_smb_list_length = -1;
514 static int hf_smb_number_of_links = -1;
515 static int hf_smb_delete_pending = -1;
516 static int hf_smb_index_number = -1;
517 static int hf_smb_current_offset = -1;
518 static int hf_smb_t2_alignment = -1;
519 static int hf_smb_t2_stream_name_length = -1;
520 static int hf_smb_t2_stream_size = -1;
521 static int hf_smb_t2_stream_name = -1;
522 static int hf_smb_t2_compressed_file_size = -1;
523 static int hf_smb_t2_compressed_format = -1;
524 static int hf_smb_t2_compressed_unit_shift = -1;
525 static int hf_smb_t2_compressed_chunk_shift = -1;
526 static int hf_smb_t2_compressed_cluster_shift = -1;
527 static int hf_smb_dfs_path_consumed = -1;
528 static int hf_smb_dfs_num_referrals = -1;
529 static int hf_smb_get_dfs_server_hold_storage = -1;
530 static int hf_smb_get_dfs_fielding = -1;
531 static int hf_smb_dfs_referral_version = -1;
532 static int hf_smb_dfs_referral_size = -1;
533 static int hf_smb_dfs_referral_server_type = -1;
534 static int hf_smb_dfs_referral_flags_strip = -1;
535 static int hf_smb_dfs_referral_node_offset = -1;
536 static int hf_smb_dfs_referral_node = -1;
537 static int hf_smb_dfs_referral_proximity = -1;
538 static int hf_smb_dfs_referral_ttl = -1;
539 static int hf_smb_dfs_referral_path_offset = -1;
540 static int hf_smb_dfs_referral_path = -1;
541 static int hf_smb_dfs_referral_alt_path_offset = -1;
542 static int hf_smb_dfs_referral_alt_path = -1;
543 static int hf_smb_end_of_search = -1;
544 static int hf_smb_last_name_offset = -1;
545 static int hf_smb_fn_information_level = -1;
546 static int hf_smb_monitor_handle = -1;
547 static int hf_smb_change_count = -1;
548 static int hf_smb_file_index = -1;
549 static int hf_smb_short_file_name = -1;
550 static int hf_smb_short_file_name_len = -1;
551 static int hf_smb_fs_id = -1;
552 static int hf_smb_sector_unit = -1;
553 static int hf_smb_fs_units = -1;
554 static int hf_smb_fs_sector = -1;
555 static int hf_smb_avail_units = -1;
556 static int hf_smb_volume_serial_num = -1;
557 static int hf_smb_volume_label_len = -1;
558 static int hf_smb_volume_label = -1;
559 static int hf_smb_free_alloc_units64 = -1;
560 static int hf_smb_caller_free_alloc_units64 = -1;
561 static int hf_smb_actual_free_alloc_units64 = -1;
562 static int hf_smb_max_name_len = -1;
563 static int hf_smb_fs_name_len = -1;
564 static int hf_smb_fs_name = -1;
565 static int hf_smb_device_char_removable = -1;
566 static int hf_smb_device_char_read_only = -1;
567 static int hf_smb_device_char_floppy = -1;
568 static int hf_smb_device_char_write_once = -1;
569 static int hf_smb_device_char_remote = -1;
570 static int hf_smb_device_char_mounted = -1;
571 static int hf_smb_device_char_virtual = -1;
572 static int hf_smb_fs_attr_css = -1;
573 static int hf_smb_fs_attr_cpn = -1;
574 static int hf_smb_fs_attr_pacls = -1;
575 static int hf_smb_fs_attr_fc = -1;
576 static int hf_smb_fs_attr_vq = -1;
577 static int hf_smb_fs_attr_dim = -1;
578 static int hf_smb_fs_attr_vic = -1;
579 static int hf_smb_quota_flags_enabled = -1;
580 static int hf_smb_quota_flags_deny_disk = -1;
581 static int hf_smb_quota_flags_log_limit = -1;
582 static int hf_smb_quota_flags_log_warning = -1;
583 static int hf_smb_soft_quota_limit = -1;
584 static int hf_smb_hard_quota_limit = -1;
585 static int hf_smb_user_quota_used = -1;
586 static int hf_smb_user_quota_offset = -1;
587 static int hf_smb_nt_rename_level = -1;
588 static int hf_smb_cluster_count = -1;
589 static int hf_smb_segments = -1;
590 static int hf_smb_segment = -1;
591 static int hf_smb_segment_overlap = -1;
592 static int hf_smb_segment_overlap_conflict = -1;
593 static int hf_smb_segment_multiple_tails = -1;
594 static int hf_smb_segment_too_long_fragment = -1;
595 static int hf_smb_segment_error = -1;
596
597 static gint ett_smb = -1;
598 static gint ett_smb_hdr = -1;
599 static gint ett_smb_command = -1;
600 static gint ett_smb_fileattributes = -1;
601 static gint ett_smb_capabilities = -1;
602 static gint ett_smb_aflags = -1;
603 static gint ett_smb_dialect = -1;
604 static gint ett_smb_dialects = -1;
605 static gint ett_smb_mode = -1;
606 static gint ett_smb_rawmode = -1;
607 static gint ett_smb_flags = -1;
608 static gint ett_smb_flags2 = -1;
609 static gint ett_smb_desiredaccess = -1;
610 static gint ett_smb_search = -1;
611 static gint ett_smb_file = -1;
612 static gint ett_smb_openfunction = -1;
613 static gint ett_smb_filetype = -1;
614 static gint ett_smb_openaction = -1;
615 static gint ett_smb_writemode = -1;
616 static gint ett_smb_lock_type = -1;
617 static gint ett_smb_ssetupandxaction = -1;
618 static gint ett_smb_optionsup = -1;
619 static gint ett_smb_time_date = -1;
620 static gint ett_smb_move_copy_flags = -1;
621 static gint ett_smb_file_attributes = -1;
622 static gint ett_smb_search_resume_key = -1;
623 static gint ett_smb_search_dir_info = -1;
624 static gint ett_smb_unlocks = -1;
625 static gint ett_smb_unlock = -1;
626 static gint ett_smb_locks = -1;
627 static gint ett_smb_lock = -1;
628 static gint ett_smb_open_flags = -1;
629 static gint ett_smb_ipc_state = -1;
630 static gint ett_smb_open_action = -1;
631 static gint ett_smb_setup_action = -1;
632 static gint ett_smb_connect_flags = -1;
633 static gint ett_smb_connect_support_bits = -1;
634 static gint ett_smb_nt_access_mask = -1;
635 static gint ett_smb_nt_create_bits = -1;
636 static gint ett_smb_nt_create_options = -1;
637 static gint ett_smb_nt_share_access = -1;
638 static gint ett_smb_nt_security_flags = -1;
639 static gint ett_smb_nt_trans_setup = -1;
640 static gint ett_smb_nt_trans_data = -1;
641 static gint ett_smb_nt_trans_param = -1;
642 static gint ett_smb_nt_notify_completion_filter = -1;
643 static gint ett_smb_nt_ioctl_flags = -1;
644 static gint ett_smb_security_information_mask = -1;
645 static gint ett_smb_print_queue_entry = -1;
646 static gint ett_smb_transaction_flags = -1;
647 static gint ett_smb_transaction_params = -1;
648 static gint ett_smb_find_first2_flags = -1;
649 static gint ett_smb_mac_support_flags = -1;
650 #if 0
651 static gint ett_smb_ioflag = -1;
652 #endif
653 static gint ett_smb_transaction_data = -1;
654 static gint ett_smb_stream_info = -1;
655 static gint ett_smb_dfs_referrals = -1;
656 static gint ett_smb_dfs_referral = -1;
657 static gint ett_smb_dfs_referral_flags = -1;
658 static gint ett_smb_get_dfs_flags = -1;
659 static gint ett_smb_ff2_data = -1;
660 static gint ett_smb_device_characteristics = -1;
661 static gint ett_smb_fs_attributes = -1;
662 static gint ett_smb_segments = -1;
663 static gint ett_smb_segment = -1;
664 static gint ett_smb_sec_desc = -1;
665 static gint ett_smb_sid = -1;
666 static gint ett_smb_acl = -1;
667 static gint ett_smb_ace = -1;
668 static gint ett_smb_ace_flags = -1;
669 static gint ett_smb_sec_desc_type = -1;
670 static gint ett_smb_quotaflags = -1;
671 static gint ett_smb_gssapi = -1;
672
673 static dissector_handle_t gssapi_handle = NULL;
674
675 fragment_items smb_frag_items = {
676         &ett_smb_segment,
677         &ett_smb_segments,
678
679         &hf_smb_segments,
680         &hf_smb_segment,
681         &hf_smb_segment_overlap,
682         &hf_smb_segment_overlap_conflict,
683         &hf_smb_segment_multiple_tails,
684         &hf_smb_segment_too_long_fragment,
685         &hf_smb_segment_error,
686
687         "segments"
688 };
689
690 proto_tree *top_tree=NULL;     /* ugly */
691
692 static char *decode_smb_name(unsigned char);
693 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu);
694
695 /*
696  * Macros for use in the main dissector routines for an SMB.
697  */
698
699 #define WORD_COUNT      \
700         /* Word Count */                                \
701         wc = tvb_get_guint8(tvb, offset);               \
702         proto_tree_add_uint(tree, hf_smb_word_count,    \
703                 tvb, offset, 1, wc);                    \
704         offset += 1;                                    \
705         if(wc==0) goto bytecount;
706
707 #define BYTE_COUNT      \
708         bytecount:                                      \
709         bc = tvb_get_letohs(tvb, offset);               \
710         proto_tree_add_uint(tree, hf_smb_byte_count,    \
711                         tvb, offset, 2, bc);            \
712         offset += 2;                                    \
713         if(bc==0) goto endofcommand;
714
715 #define CHECK_BYTE_COUNT(len)   \
716         if (bc < len) goto endofcommand;
717
718 #define COUNT_BYTES(len)   {\
719         int tmp;            \
720         tmp=len;            \
721         offset += tmp;      \
722         bc -= tmp;          \
723         }
724
725 #define END_OF_SMB      \
726         if (bc != 0) { \
727                 proto_tree_add_text(tree, tvb, offset, bc, \
728                     "Extra byte parameters");           \
729                 offset += bc;                           \
730         }                                               \
731         endofcommand:
732
733 /*
734  * Macros for use in routines called by them.
735  */
736 #define CHECK_BYTE_COUNT_SUBR(len)      \
737         if (*bcp < len) {               \
738                 *trunc = TRUE;          \
739                 return offset;          \
740         }
741
742 #define CHECK_STRING_SUBR(fn)   \
743         if (fn == NULL) {       \
744                 *trunc = TRUE;  \
745                 return offset;  \
746         }
747
748 #define COUNT_BYTES_SUBR(len)   \
749         offset += len;          \
750         *bcp -= len;
751
752 /*
753  * Macros for use when dissecting transaction parameters and data
754  */
755 #define CHECK_BYTE_COUNT_TRANS(len)     \
756         if (bc < len) return offset;
757
758 #define CHECK_STRING_TRANS(fn)  \
759         if (fn == NULL) return offset;
760
761 #define COUNT_BYTES_TRANS(len)  \
762         offset += len;          \
763         bc -= len;
764
765 /*
766  * Macros for use in subrroutines dissecting transaction parameters or data
767  */
768 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
769         if (*bcp < len) return offset;
770
771 #define CHECK_STRING_TRANS_SUBR(fn)     \
772         if (fn == NULL) return offset;
773
774 #define COUNT_BYTES_TRANS_SUBR(len)     \
775         offset += len;                  \
776         *bcp -= len;
777
778
779 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
780    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
781    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
782 static gboolean smb_trans_reassembly = FALSE;
783 gboolean smb_dcerpc_reassembly = FALSE;
784
785 static GHashTable *smb_trans_fragment_table = NULL;
786 GHashTable *dcerpc_fragment_table = NULL;
787
788 static void
789 smb_trans_reassembly_init(void)
790 {
791         fragment_table_init(&smb_trans_fragment_table);
792 }
793 static void
794 smb_dcerpc_reassembly_init(void)
795 {
796         fragment_table_init(&dcerpc_fragment_table);
797 }
798
799
800 static fragment_data *
801 smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
802                      int offset, int count, int pos, int totlen)
803 {
804         fragment_data *fd_head=NULL;
805         smb_info_t *si;
806         int more_frags;
807
808         more_frags=totlen>(pos+count);
809
810         si = (smb_info_t *)pinfo->private_data;
811         if (si->sip == NULL) {
812                 /*
813                  * We don't have the frame number of the request.
814                  *
815                  * XXX - is there truly nothing we can do here?
816                  * Can we not separately keep track of the original
817                  * transaction and its continuations, as we did
818                  * at one time?
819                  *
820                  * It is probably not much point in even trying to do something here
821                  * if we have never seen the initial request. Without the initial
822                  * request we probably miss all parameters and the begining of data
823                  * so we cant even call a subdissector since we can not determine
824                  * which type of transaction call this is.
825                  */
826                 return NULL;
827         }
828
829         if(!pinfo->fd->flags.visited){
830                 fd_head = fragment_add(tvb, offset, pinfo,
831                                        si->sip->frame_req, smb_trans_fragment_table,
832                                        pos, count, more_frags);
833         } else {
834                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
835         }
836
837         /* we only show the defragmented packet for the first fragment,
838            or else we might end up with dissecting one HUGE transaction PDU
839            a LOT of times. (first fragment is the only one containing the setup
840            bytes)
841            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction
842            SMBs. Takes a LOT of time dissecting and is not fun.
843         */
844         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
845                 return fd_head;
846         } else {
847                 return NULL;
848         }
849 }
850
851
852
853
854
855 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
856    These variables and functions are used to match
857    responses with calls
858    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
859 /*
860  * The information we need to save about a request in order to show the
861  * frame number of the request in the dissection of the reply.
862  */
863 typedef struct  {
864         guint32 frame;
865         guint32 pid_mid;
866 } smb_saved_info_key_t;
867
868 static GMemChunk *smb_saved_info_key_chunk = NULL;
869 static GMemChunk *smb_saved_info_chunk = NULL;
870 static int smb_saved_info_init_count = 200;
871
872 /* unmatched smb_saved_info structures.
873    For unmatched smb_saved_info structures we store the smb_saved_info
874    structure using the MID and the PID as the key.
875
876    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
877    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
878    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
879 */
880 static gint
881 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
882 {
883         register guint32 key1 = (guint32)k1;
884         register guint32 key2 = (guint32)k2;
885         return key1==key2;
886 }
887 static guint
888 smb_saved_info_hash_unmatched(gconstpointer k)
889 {
890         register guint32 key = (guint32)k;
891         return key;
892 }
893
894 /* matched smb_saved_info structures.
895    For matched smb_saved_info structures we store the smb_saved_info
896    structure twice in the table using the frame number, and a combination
897    of the MID and the PID, as the key.
898    The frame number is guaranteed to be unique but if ever someone makes
899    some change that will renumber the frames in a capture we are in BIG trouble.
900    This is not likely though since that would break (among other things) all the
901    reassembly routines as well.
902
903    We also need the MID as there may be more than one SMB request or reply
904    in a single frame, and we also need the PID as there may be more than
905    one outstanding request with the same MID and different PIDs.
906 */
907 static gint
908 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
909 {
910         const smb_saved_info_key_t *key1 = k1;
911         const smb_saved_info_key_t *key2 = k2;
912         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
913 }
914 static guint
915 smb_saved_info_hash_matched(gconstpointer k)
916 {
917         const smb_saved_info_key_t *key = k;
918         return key->frame + key->pid_mid;
919 }
920
921 /*
922  * The information we need to save about an NT Transaction request in order
923  * to dissect the reply.
924  */
925 typedef struct {
926         int subcmd;
927 } smb_nt_transact_info_t;
928
929 static GMemChunk *smb_nt_transact_info_chunk = NULL;
930 static int smb_nt_transact_info_init_count = 200;
931
932 /*
933  * The information we need to save about a Transaction2 request in order
934  * to dissect the reply.
935  */
936 typedef struct {
937         int subcmd;
938         int info_level;
939         gboolean resume_keys;   /* if "return resume" keys set in T2 FIND_FIRST request */
940 } smb_transact2_info_t;
941
942 static GMemChunk *smb_transact2_info_chunk = NULL;
943 static int smb_transact2_info_init_count = 200;
944
945 /*
946  * The information we need to save about a Transaction request in order
947  * to dissect the reply; this includes information for use by the
948  * Remote API dissector.
949  */
950 static GMemChunk *smb_transact_info_chunk = NULL;
951 static int smb_transact_info_init_count = 200;
952
953 static GMemChunk *conv_tables_chunk = NULL;
954 static GSList *conv_tables = NULL;
955 static int conv_tables_count = 10;
956
957
958 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
959    End of request/response matching functions
960    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
961
962 static const value_string buffer_format_vals[] = {
963         {1,     "Data Block"},
964         {2,     "Dialect"},
965         {3,     "Pathname"},
966         {4,     "ASCII"},
967         {5,     "Variable Block"},
968         {0,     NULL}
969 };
970
971 /*
972  * UTIME - this is *almost* like a UNIX time stamp, except that it's
973  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
974  * January 1, 1970, 00:00:00 GMT.
975  *
976  * This means we have to do some extra work to convert it.  This code is
977  * based on the Samba code:
978  *
979  *      Unix SMB/Netbios implementation.
980  *      Version 1.9.
981  *      time handling functions
982  *      Copyright (C) Andrew Tridgell 1992-1998
983  */
984
985 /*
986  * Yield the difference between *A and *B, in seconds, ignoring leap
987  * seconds.
988  */
989 #define TM_YEAR_BASE 1900
990
991 static int
992 tm_diff(struct tm *a, struct tm *b)
993 {
994         int ay = a->tm_year + (TM_YEAR_BASE - 1);
995         int by = b->tm_year + (TM_YEAR_BASE - 1);
996         int intervening_leap_days =
997             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
998         int years = ay - by;
999         int days =
1000             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
1001         int hours = 24*days + (a->tm_hour - b->tm_hour);
1002         int minutes = 60*hours + (a->tm_min - b->tm_min);
1003         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
1004
1005         return seconds;
1006 }
1007
1008 /*
1009  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
1010  * determined.
1011  */
1012 static int
1013 TimeZone(time_t t)
1014 {
1015         struct tm *tm = gmtime(&t);
1016         struct tm tm_utc;
1017
1018         if (tm == NULL)
1019                 return 0;
1020         tm_utc = *tm;
1021         tm = localtime(&t);
1022         if (tm == NULL)
1023                 return 0;
1024         return tm_diff(&tm_utc,tm);
1025 }
1026
1027 /*
1028  * Return the same value as TimeZone, but it should be more efficient.
1029  *
1030  * We keep a table of DST offsets to prevent calling localtime() on each
1031  * call of this function. This saves a LOT of time on many unixes.
1032  *
1033  * Updated by Paul Eggert <eggert@twinsun.com>
1034  */
1035 #ifndef CHAR_BIT
1036 #define CHAR_BIT 8
1037 #endif
1038
1039 #ifndef TIME_T_MIN
1040 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1041                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
1042 #endif
1043 #ifndef TIME_T_MAX
1044 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
1045 #endif
1046
1047 static int
1048 TimeZoneFaster(time_t t)
1049 {
1050         static struct dst_table {time_t start,end; int zone;} *tdt;
1051         static struct dst_table *dst_table = NULL;
1052         static int table_size = 0;
1053         int i;
1054         int zone = 0;
1055
1056         if (t == 0)
1057                 t = time(NULL);
1058
1059         /* Tunis has a 8 day DST region, we need to be careful ... */
1060 #define MAX_DST_WIDTH (365*24*60*60)
1061 #define MAX_DST_SKIP (7*24*60*60)
1062
1063         for (i = 0; i < table_size; i++) {
1064                 if (t >= dst_table[i].start && t <= dst_table[i].end)
1065                         break;
1066         }
1067
1068         if (i < table_size) {
1069                 zone = dst_table[i].zone;
1070         } else {
1071                 time_t low,high;
1072
1073                 zone = TimeZone(t);
1074                 if (dst_table == NULL)
1075                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1076                 else
1077                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1078                 if (tdt == NULL) {
1079                         if (dst_table)
1080                                 free(dst_table);
1081                         table_size = 0;
1082                 } else {
1083                         dst_table = tdt;
1084                         table_size++;
1085
1086                         dst_table[i].zone = zone;
1087                         dst_table[i].start = dst_table[i].end = t;
1088
1089                         /* no entry will cover more than 6 months */
1090                         low = t - MAX_DST_WIDTH/2;
1091                         if (t < low)
1092                                 low = TIME_T_MIN;
1093
1094                         high = t + MAX_DST_WIDTH/2;
1095                         if (high < t)
1096                                 high = TIME_T_MAX;
1097
1098                         /*
1099                          * Widen the new entry using two bisection searches.
1100                          */
1101                         while (low+60*60 < dst_table[i].start) {
1102                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1103                                         t = dst_table[i].start - MAX_DST_SKIP;
1104                                 else
1105                                         t = low + (dst_table[i].start-low)/2;
1106                                 if (TimeZone(t) == zone)
1107                                         dst_table[i].start = t;
1108                                 else
1109                                         low = t;
1110                         }
1111
1112                         while (high-60*60 > dst_table[i].end) {
1113                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1114                                         t = dst_table[i].end + MAX_DST_SKIP;
1115                                 else
1116                                         t = high - (high-dst_table[i].end)/2;
1117                                 if (TimeZone(t) == zone)
1118                                         dst_table[i].end = t;
1119                                 else
1120                                         high = t;
1121                         }
1122                 }
1123         }
1124         return zone;
1125 }
1126
1127 /*
1128  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1129  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1130  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1131  * daylight savings transitions because some local times are ambiguous.
1132  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1133  */
1134 static int
1135 LocTimeDiff(time_t lt)
1136 {
1137         int d = TimeZoneFaster(lt);
1138         time_t t = lt + d;
1139
1140         /* if overflow occurred, ignore all the adjustments so far */
1141         if (((t < lt) ^ (d < 0)))
1142                 t = lt;
1143
1144         /*
1145          * Now t should be close enough to the true UTC to yield the
1146          * right answer.
1147          */
1148         return TimeZoneFaster(t);
1149 }
1150
1151 static int
1152 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1153 {
1154         guint32 timeval;
1155         nstime_t ts;
1156
1157         timeval = tvb_get_letohl(tvb, offset);
1158         if (timeval == 0xffffffff) {
1159                 proto_tree_add_text(tree, tvb, offset, 4,
1160                     "%s: No time specified (0xffffffff)",
1161                     proto_registrar_get_name(hf_date));
1162                 offset += 4;
1163                 return offset;
1164         }
1165
1166         /*
1167          * We add the local time offset.
1168          */
1169         ts.secs = timeval + LocTimeDiff(timeval);
1170         ts.nsecs = 0;
1171
1172         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1173         offset += 4;
1174
1175         return offset;
1176 }
1177
1178 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
1179
1180 /*
1181  * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits,
1182  * to an "nstime_t".
1183  * A FILETIME is a 64-bit integer, giving the time since Jan 1, 1601,
1184  * midnight "UTC", in 100ns units.
1185  * Return TRUE if the conversion succeeds, FALSE otherwise.
1186  *
1187  * According to the Samba code, it appears to be kludge-GMT (at least for
1188  * file listings). This means it's the GMT you get by taking a local time
1189  * and adding the server time zone offset.  This is NOT the same as GMT in
1190  * some cases.   However, we don't know the server time zone, so we don't
1191  * do that adjustment.
1192  *
1193  * This code is based on the Samba code:
1194  *
1195  *      Unix SMB/Netbios implementation.
1196  *      Version 1.9.
1197  *      time handling functions
1198  *      Copyright (C) Andrew Tridgell 1992-1998
1199  */
1200 static gboolean
1201 nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
1202 {
1203         double d;
1204         /* The next two lines are a fix needed for the
1205             broken SCO compiler. JRA. */
1206         time_t l_time_min = TIME_T_MIN;
1207         time_t l_time_max = TIME_T_MAX;
1208
1209         if (filetime_high == 0)
1210                 return FALSE;
1211
1212         /*
1213          * Get the time as a double, in seconds and fractional seconds.
1214          */
1215         d = ((double)filetime_high)*4.0*(double)(1<<30);
1216         d += filetime_low;
1217         d *= 1.0e-7;
1218
1219         /* Now adjust by 369 years, to make the seconds since 1970. */
1220         d -= TIME_FIXUP_CONSTANT;
1221
1222         if (!(l_time_min <= d && d <= l_time_max))
1223                 return FALSE;
1224
1225         /*
1226          * Get the time as seconds and nanoseconds.
1227          */
1228         tv->secs = d;
1229         tv->nsecs = (d - tv->secs)*1000000000;
1230
1231         return TRUE;
1232 }
1233
1234 int
1235 dissect_smb_64bit_time(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1236 {
1237         guint32 filetime_high, filetime_low;
1238         nstime_t ts;
1239
1240         /* XXX there seems also to be another special time value which is fairly common :
1241            0x40000000 00000000
1242            the meaning of this one is yet unknown
1243         */
1244         if (tree) {
1245                 filetime_low = tvb_get_letohl(tvb, offset);
1246                 filetime_high = tvb_get_letohl(tvb, offset + 4);
1247                 if (filetime_low == 0 && filetime_high == 0) {
1248                         proto_tree_add_text(tree, tvb, offset, 8,
1249                             "%s: No time specified (0)",
1250                             proto_registrar_get_name(hf_date));
1251                 } else if(filetime_low==0 && filetime_high==0x80000000){
1252                         proto_tree_add_text(tree, tvb, offset, 8,
1253                             "%s: Infinity (relative time)",
1254                             proto_registrar_get_name(hf_date));
1255                 } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
1256                         proto_tree_add_text(tree, tvb, offset, 8,
1257                             "%s: Infinity (absolute time)",
1258                             proto_registrar_get_name(hf_date));
1259                 } else {
1260                         if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
1261                                 proto_tree_add_time(tree, hf_date, tvb,
1262                                     offset, 8, &ts);
1263                         } else {
1264                                 proto_tree_add_text(tree, tvb, offset, 8,
1265                                     "%s: Time can't be converted",
1266                                     proto_registrar_get_name(hf_date));
1267                         }
1268                 }
1269         }
1270
1271         offset += 8;
1272         return offset;
1273 }
1274
1275 static int
1276 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1277     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1278 {
1279         guint16 dos_time, dos_date;
1280         proto_item *item = NULL;
1281         proto_tree *tree = NULL;
1282         struct tm tm;
1283         time_t t;
1284         static const int mday_noleap[12] = {
1285                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1286         };
1287         static const int mday_leap[12] = {
1288                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1289         };
1290 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1291         nstime_t tv;
1292
1293         if (time_first) {
1294                 dos_time = tvb_get_letohs(tvb, offset);
1295                 dos_date = tvb_get_letohs(tvb, offset+2);
1296         } else {
1297                 dos_date = tvb_get_letohs(tvb, offset);
1298                 dos_time = tvb_get_letohs(tvb, offset+2);
1299         }
1300
1301         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1302             (dos_date == 0 && dos_time == 0)) {
1303                 /*
1304                  * No date/time specified.
1305                  */
1306                 if(parent_tree){
1307                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1308                             "%s: No time specified (0x%08x)",
1309                             proto_registrar_get_name(hf_date),
1310                             (dos_date << 16) | dos_time);
1311                 }
1312                 offset += 4;
1313                 return offset;
1314         }
1315
1316         tm.tm_sec = (dos_time&0x1f)*2;
1317         tm.tm_min = (dos_time>>5)&0x3f;
1318         tm.tm_hour = (dos_time>>11)&0x1f;
1319         tm.tm_mday = dos_date&0x1f;
1320         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1321         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1322         tm.tm_isdst = -1;
1323
1324         /*
1325          * Do some sanity checks before calling "mktime()";
1326          * "mktime()" doesn't do them, it "normalizes" out-of-range
1327          * values.
1328          */
1329         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1330            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1331            (ISLEAP(tm.tm_year + 1900) ?
1332              tm.tm_mday > mday_leap[tm.tm_mon] :
1333              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1334              (t = mktime(&tm)) == -1) {
1335                 /*
1336                  * Invalid date/time.
1337                  */
1338                 if (parent_tree) {
1339                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1340                             "%s: Invalid time",
1341                             proto_registrar_get_name(hf_date));
1342                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1343                         if (time_first) {
1344                                 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);
1345                                 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);
1346                         } else {
1347                                 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);
1348                                 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);
1349                         }
1350                 }
1351                 offset += 4;
1352                 return offset;
1353         }
1354
1355         tv.secs = t;
1356         tv.nsecs = 0;
1357
1358         if(parent_tree){
1359                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1360                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1361                 if (time_first) {
1362                         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);
1363                         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);
1364                 } else {
1365                         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);
1366                         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);
1367                 }
1368         }
1369
1370         offset += 4;
1371
1372         return offset;
1373 }
1374
1375
1376 static const value_string da_access_vals[] = {
1377         { 0,            "Open for reading"},
1378         { 1,            "Open for writing"},
1379         { 2,            "Open for reading and writing"},
1380         { 3,            "Open for execute"},
1381         {0, NULL}
1382 };
1383 static const value_string da_sharing_vals[] = {
1384         { 0,            "Compatibility mode"},
1385         { 1,            "Deny read/write/execute (exclusive)"},
1386         { 2,            "Deny write"},
1387         { 3,            "Deny read/execute"},
1388         { 4,            "Deny none"},
1389         {0, NULL}
1390 };
1391 static const value_string da_locality_vals[] = {
1392         { 0,            "Locality of reference unknown"},
1393         { 1,            "Mainly sequential access"},
1394         { 2,            "Mainly random access"},
1395         { 3,            "Random access with some locality"},
1396         {0, NULL}
1397 };
1398 static const true_false_string tfs_da_caching = {
1399         "Do not cache this file",
1400         "Caching permitted on this file"
1401 };
1402 static const true_false_string tfs_da_writetru = {
1403         "Write through enabled",
1404         "Write through disabled"
1405 };
1406 static int
1407 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, char *type)
1408 {
1409         guint16 mask;
1410         proto_item *item = NULL;
1411         proto_tree *tree = NULL;
1412
1413         mask = tvb_get_letohs(tvb, offset);
1414
1415         if(parent_tree){
1416                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1417                         "%s Access: 0x%04x", type, mask);
1418                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1419         }
1420
1421         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1422                 tvb, offset, 2, mask);
1423         proto_tree_add_boolean(tree, hf_smb_access_caching,
1424                 tvb, offset, 2, mask);
1425         proto_tree_add_uint(tree, hf_smb_access_locality,
1426                 tvb, offset, 2, mask);
1427         proto_tree_add_uint(tree, hf_smb_access_sharing,
1428                 tvb, offset, 2, mask);
1429         proto_tree_add_uint(tree, hf_smb_access_mode,
1430                 tvb, offset, 2, mask);
1431
1432         offset += 2;
1433
1434         return offset;
1435 }
1436
1437 #define FILE_ATTRIBUTE_READ_ONLY                0x00000001
1438 #define FILE_ATTRIBUTE_HIDDEN                   0x00000002
1439 #define FILE_ATTRIBUTE_SYSTEM                   0x00000004
1440 #define FILE_ATTRIBUTE_VOLUME                   0x00000008
1441 #define FILE_ATTRIBUTE_DIRECTORY                0x00000010
1442 #define FILE_ATTRIBUTE_ARCHIVE                  0x00000020
1443 #define FILE_ATTRIBUTE_DEVICE                   0x00000040
1444 #define FILE_ATTRIBUTE_NORMAL                   0x00000080
1445 #define FILE_ATTRIBUTE_TEMPORARY                0x00000100
1446 #define FILE_ATTRIBUTE_SPARSE                   0x00000200
1447 #define FILE_ATTRIBUTE_REPARSE                  0x00000400
1448 #define FILE_ATTRIBUTE_COMPRESSED               0x00000800
1449 #define FILE_ATTRIBUTE_OFFLINE                  0x00001000
1450 #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED      0x00002000
1451 #define FILE_ATTRIBUTE_ENCRYPTED                0x00004000
1452
1453 /*
1454  * These are flags to be used in NT Create operations.
1455  */
1456 #define FILE_ATTRIBUTE_WRITE_THROUGH            0x80000000
1457 #define FILE_ATTRIBUTE_NO_BUFFERING             0x20000000
1458 #define FILE_ATTRIBUTE_RANDOM_ACCESS            0x10000000
1459 #define FILE_ATTRIBUTE_SEQUENTIAL_SCAN          0x08000000
1460 #define FILE_ATTRIBUTE_DELETE_ON_CLOSE          0x04000000
1461 #define FILE_ATTRIBUTE_BACKUP_SEMANTICS         0x02000000
1462 #define FILE_ATTRIBUTE_POSIX_SEMANTICS          0x01000000
1463
1464 static const true_false_string tfs_file_attribute_write_through = {
1465         "This object requires WRITE THROUGH",
1466         "This object does NOT require write through",
1467 };
1468 static const true_false_string tfs_file_attribute_no_buffering = {
1469         "This object requires NO BUFFERING",
1470         "This object can be buffered",
1471 };
1472 static const true_false_string tfs_file_attribute_random_access = {
1473         "This object will be RANDOM ACCESSed",
1474         "Random access is NOT requested",
1475 };
1476 static const true_false_string tfs_file_attribute_sequential_scan = {
1477         "This object is optimized for SEQUENTIAL SCAN",
1478         "This object is NOT optimized for sequential scan",
1479 };
1480 static const true_false_string tfs_file_attribute_delete_on_close = {
1481         "This object will be DELETED ON CLOSE",
1482         "This object will not be deleted on close",
1483 };
1484 static const true_false_string tfs_file_attribute_backup_semantics = {
1485         "This object supports BACKUP SEMANTICS",
1486         "This object does NOT support backup semantics",
1487 };
1488 static const true_false_string tfs_file_attribute_posix_semantics = {
1489         "This object supports POSIX SEMANTICS",
1490         "This object does NOT support POSIX semantics",
1491 };
1492 static const true_false_string tfs_file_attribute_read_only = {
1493         "This file is READ ONLY",
1494         "This file is NOT read only",
1495 };
1496 static const true_false_string tfs_file_attribute_hidden = {
1497         "This is a HIDDEN file",
1498         "This is NOT a hidden file"
1499 };
1500 static const true_false_string tfs_file_attribute_system = {
1501         "This is a SYSTEM file",
1502         "This is NOT a system file"
1503 };
1504 static const true_false_string tfs_file_attribute_volume = {
1505         "This is a VOLUME ID",
1506         "This is NOT a volume ID"
1507 };
1508 static const true_false_string tfs_file_attribute_directory = {
1509         "This is a DIRECTORY",
1510         "This is NOT a directory"
1511 };
1512 static const true_false_string tfs_file_attribute_archive = {
1513         "This is an ARCHIVE file",
1514         "This is NOT an archive file"
1515 };
1516 static const true_false_string tfs_file_attribute_device = {
1517         "This is a DEVICE",
1518         "This is NOT a device"
1519 };
1520 static const true_false_string tfs_file_attribute_normal = {
1521         "This file is an ordinary file",
1522         "This file has some attribute set"
1523 };
1524 static const true_false_string tfs_file_attribute_temporary = {
1525         "This is a TEMPORARY file",
1526         "This is NOT a temporary file"
1527 };
1528 static const true_false_string tfs_file_attribute_sparse = {
1529         "This is a SPARSE file",
1530         "This is NOT a sparse file"
1531 };
1532 static const true_false_string tfs_file_attribute_reparse = {
1533         "This file has an associated REPARSE POINT",
1534         "This file does NOT have an associated reparse point"
1535 };
1536 static const true_false_string tfs_file_attribute_compressed = {
1537         "This is a COMPRESSED file",
1538         "This is NOT a compressed file"
1539 };
1540 static const true_false_string tfs_file_attribute_offline = {
1541         "This file is OFFLINE",
1542         "This file is NOT offline"
1543 };
1544 static const true_false_string tfs_file_attribute_not_content_indexed = {
1545         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1546         "This file MAY be indexed by the content indexing service"
1547 };
1548 static const true_false_string tfs_file_attribute_encrypted = {
1549         "This is an ENCRYPTED file",
1550         "This is NOT an encrypted file"
1551 };
1552
1553 static int
1554 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1555 {
1556         guint16 mask;
1557         proto_item *item = NULL;
1558         proto_tree *tree = NULL;
1559
1560         mask = tvb_get_letohs(tvb, offset);
1561
1562         if(parent_tree){
1563                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1564                         "File Attributes: 0x%04x", mask);
1565                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1566         }
1567         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1568                 tvb, offset, 2, mask);
1569         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1570                 tvb, offset, 2, mask);
1571         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1572                 tvb, offset, 2, mask);
1573         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1574                 tvb, offset, 2, mask);
1575         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1576                 tvb, offset, 2, mask);
1577         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1578                 tvb, offset, 2, mask);
1579
1580         offset += 2;
1581
1582         return offset;
1583 }
1584
1585 /* 3.11 */
1586 static int
1587 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1588 {
1589         guint32 mask;
1590         proto_item *item = NULL;
1591         proto_tree *tree = NULL;
1592
1593         mask = tvb_get_letohl(tvb, offset);
1594
1595         if(parent_tree){
1596                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1597                         "File Attributes: 0x%08x", mask);
1598                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1599         }
1600
1601         /*
1602          * XXX - Network Monitor disagrees on some of the
1603          * bits, e.g. the bits above temporary are "atomic write"
1604          * and "transaction write", and it says nothing about the
1605          * bits above that.
1606          *
1607          * Does the Win32 API documentation, or the NT Native API book,
1608          * suggest anything?
1609          */
1610         proto_tree_add_boolean(tree, hf_smb_file_eattr_write_through,
1611                 tvb, offset, 4, mask);
1612         proto_tree_add_boolean(tree, hf_smb_file_eattr_no_buffering,
1613                 tvb, offset, 4, mask);
1614         proto_tree_add_boolean(tree, hf_smb_file_eattr_random_access,
1615                 tvb, offset, 4, mask);
1616         proto_tree_add_boolean(tree, hf_smb_file_eattr_sequential_scan,
1617                 tvb, offset, 4, mask);
1618         proto_tree_add_boolean(tree, hf_smb_file_eattr_delete_on_close,
1619                 tvb, offset, 4, mask);
1620         proto_tree_add_boolean(tree, hf_smb_file_eattr_backup_semantics,
1621                 tvb, offset, 4, mask);
1622         proto_tree_add_boolean(tree, hf_smb_file_eattr_posix_semantics,
1623                 tvb, offset, 4, mask);
1624         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1625                 tvb, offset, 4, mask);
1626         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1627                 tvb, offset, 4, mask);
1628         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1629                 tvb, offset, 4, mask);
1630         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1631                 tvb, offset, 4, mask);
1632         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1633                 tvb, offset, 4, mask);
1634         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1635                 tvb, offset, 4, mask);
1636         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1637                 tvb, offset, 4, mask);
1638         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1639                 tvb, offset, 4, mask);
1640         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1641                 tvb, offset, 4, mask);
1642         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1643                 tvb, offset, 4, mask);
1644         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1645                 tvb, offset, 4, mask);
1646         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1647                 tvb, offset, 4, mask);
1648         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1649                 tvb, offset, 4, mask);
1650         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1651                 tvb, offset, 4, mask);
1652         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1653                 tvb, offset, 4, mask);
1654
1655         offset += 4;
1656
1657         return offset;
1658 }
1659
1660 static int
1661 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1662 {
1663         guint8 mask;
1664         proto_item *item = NULL;
1665         proto_tree *tree = NULL;
1666
1667         mask = tvb_get_guint8(tvb, offset);
1668
1669         if(parent_tree){
1670                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1671                         "File Attributes: 0x%02x", mask);
1672                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1673         }
1674         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1675                 tvb, offset, 1, mask);
1676         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1677                 tvb, offset, 1, mask);
1678         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1679                 tvb, offset, 1, mask);
1680         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1681                 tvb, offset, 1, mask);
1682         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1683                 tvb, offset, 1, mask);
1684         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1685                 tvb, offset, 1, mask);
1686
1687         offset += 1;
1688
1689         return offset;
1690 }
1691
1692 static const true_false_string tfs_search_attribute_read_only = {
1693         "Include READ ONLY files in search results",
1694         "Do NOT include read only files in search results",
1695 };
1696 static const true_false_string tfs_search_attribute_hidden = {
1697         "Include HIDDEN files in search results",
1698         "Do NOT include hidden files in search results"
1699 };
1700 static const true_false_string tfs_search_attribute_system = {
1701         "Include SYSTEM files in search results",
1702         "Do NOT include system files in search results"
1703 };
1704 static const true_false_string tfs_search_attribute_volume = {
1705         "Include VOLUME IDs in search results",
1706         "Do NOT include volume IDs in search results"
1707 };
1708 static const true_false_string tfs_search_attribute_directory = {
1709         "Include DIRECTORIES in search results",
1710         "Do NOT include directories in search results"
1711 };
1712 static const true_false_string tfs_search_attribute_archive = {
1713         "Include ARCHIVE files in search results",
1714         "Do NOT include archive files in search results"
1715 };
1716
1717 static int
1718 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1719 {
1720         guint16 mask;
1721         proto_item *item = NULL;
1722         proto_tree *tree = NULL;
1723
1724         mask = tvb_get_letohs(tvb, offset);
1725
1726         if(parent_tree){
1727                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1728                         "Search Attributes: 0x%04x", mask);
1729                 tree = proto_item_add_subtree(item, ett_smb_search);
1730         }
1731
1732         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1733                 tvb, offset, 2, mask);
1734         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1735                 tvb, offset, 2, mask);
1736         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1737                 tvb, offset, 2, mask);
1738         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1739                 tvb, offset, 2, mask);
1740         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1741                 tvb, offset, 2, mask);
1742         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1743                 tvb, offset, 2, mask);
1744
1745         offset += 2;
1746         return offset;
1747 }
1748
1749 #if 0
1750 /*
1751  * XXX - this isn't used.
1752  * Is this used for anything?  NT Create AndX doesn't use it.
1753  * Is there some 16-bit attribute field with more bits than Read Only,
1754  * Hidden, System, Volume ID, Directory, and Archive?
1755  */
1756 static int
1757 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1758 {
1759         guint32 mask;
1760         proto_item *item = NULL;
1761         proto_tree *tree = NULL;
1762
1763         mask = tvb_get_letohl(tvb, offset);
1764
1765         if(parent_tree){
1766                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1767                         "File Attributes: 0x%08x", mask);
1768                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1769         }
1770         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1771                 tvb, offset, 2, mask);
1772         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1773                 tvb, offset, 2, mask);
1774         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1775                 tvb, offset, 2, mask);
1776         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1777                 tvb, offset, 2, mask);
1778         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1779                 tvb, offset, 2, mask);
1780         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1781                 tvb, offset, 2, mask);
1782         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1783                 tvb, offset, 2, mask);
1784         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1785                 tvb, offset, 2, mask);
1786         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1787                 tvb, offset, 2, mask);
1788         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1789                 tvb, offset, 2, mask);
1790         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1791                 tvb, offset, 2, mask);
1792         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1793                 tvb, offset, 2, mask);
1794         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1795                 tvb, offset, 2, mask);
1796         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1797                 tvb, offset, 2, mask);
1798         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1799                 tvb, offset, 2, mask);
1800
1801         offset += 2;
1802
1803         return offset;
1804 }
1805 #endif
1806
1807
1808 #define SERVER_CAP_RAW_MODE            0x00000001
1809 #define SERVER_CAP_MPX_MODE            0x00000002
1810 #define SERVER_CAP_UNICODE             0x00000004
1811 #define SERVER_CAP_LARGE_FILES         0x00000008
1812 #define SERVER_CAP_NT_SMBS             0x00000010
1813 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1814 #define SERVER_CAP_STATUS32            0x00000040
1815 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1816 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1817 #define SERVER_CAP_NT_FIND             0x00000200
1818 #define SERVER_CAP_DFS                 0x00001000
1819 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1820 #define SERVER_CAP_LARGE_READX         0x00004000
1821 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1822 #define SERVER_CAP_UNIX                0x00800000
1823 #define SERVER_CAP_RESERVED            0x02000000
1824 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1825 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1826 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1827 static const true_false_string tfs_server_cap_raw_mode = {
1828         "Read Raw and Write Raw are supported",
1829         "Read Raw and Write Raw are not supported"
1830 };
1831 static const true_false_string tfs_server_cap_mpx_mode = {
1832         "Read Mpx and Write Mpx are supported",
1833         "Read Mpx and Write Mpx are not supported"
1834 };
1835 static const true_false_string tfs_server_cap_unicode = {
1836         "Unicode strings are supported",
1837         "Unicode strings are not supported"
1838 };
1839 static const true_false_string tfs_server_cap_large_files = {
1840         "Large files are supported",
1841         "Large files are not supported",
1842 };
1843 static const true_false_string tfs_server_cap_nt_smbs = {
1844         "NT SMBs are supported",
1845         "NT SMBs are not supported"
1846 };
1847 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1848         "RPC remote APIs are supported",
1849         "RPC remote APIs are not supported"
1850 };
1851 static const true_false_string tfs_server_cap_nt_status = {
1852         "NT status codes are supported",
1853         "NT status codes are not supported"
1854 };
1855 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1856         "Level 2 oplocks are supported",
1857         "Level 2 oplocks are not supported"
1858 };
1859 static const true_false_string tfs_server_cap_lock_and_read = {
1860         "Lock and Read is supported",
1861         "Lock and Read is not supported"
1862 };
1863 static const true_false_string tfs_server_cap_nt_find = {
1864         "NT Find is supported",
1865         "NT Find is not supported"
1866 };
1867 static const true_false_string tfs_server_cap_dfs = {
1868         "Dfs is supported",
1869         "Dfs is not supported"
1870 };
1871 static const true_false_string tfs_server_cap_infolevel_passthru = {
1872         "NT information level request passthrough is supported",
1873         "NT information level request passthrough is not supported"
1874 };
1875 static const true_false_string tfs_server_cap_large_readx = {
1876         "Large Read andX is supported",
1877         "Large Read andX is not supported"
1878 };
1879 static const true_false_string tfs_server_cap_large_writex = {
1880         "Large Write andX is supported",
1881         "Large Write andX is not supported"
1882 };
1883 static const true_false_string tfs_server_cap_unix = {
1884         "UNIX extensions are supported",
1885         "UNIX extensions are not supported"
1886 };
1887 static const true_false_string tfs_server_cap_reserved = {
1888         "Reserved",
1889         "Reserved"
1890 };
1891 static const true_false_string tfs_server_cap_bulk_transfer = {
1892         "Bulk Read and Bulk Write are supported",
1893         "Bulk Read and Bulk Write are not supported"
1894 };
1895 static const true_false_string tfs_server_cap_compressed_data = {
1896         "Compressed data transfer is supported",
1897         "Compressed data transfer is not supported"
1898 };
1899 static const true_false_string tfs_server_cap_extended_security = {
1900         "Extended security exchanges are supported",
1901         "Extended security exchanges are not supported"
1902 };
1903 static int
1904 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1905 {
1906         guint32 mask;
1907         proto_item *item = NULL;
1908         proto_tree *tree = NULL;
1909
1910         mask = tvb_get_letohl(tvb, offset);
1911
1912         if(parent_tree){
1913                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1914                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1915         }
1916
1917         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1918                 tvb, offset, 4, mask);
1919         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1920                 tvb, offset, 4, mask);
1921         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1922                 tvb, offset, 4, mask);
1923         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1924                 tvb, offset, 4, mask);
1925         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1926                 tvb, offset, 4, mask);
1927         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1928                 tvb, offset, 4, mask);
1929         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1930                 tvb, offset, 4, mask);
1931         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1932                 tvb, offset, 4, mask);
1933         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1934                 tvb, offset, 4, mask);
1935         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1936                 tvb, offset, 4, mask);
1937         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1938                 tvb, offset, 4, mask);
1939         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1940                 tvb, offset, 4, mask);
1941         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1942                 tvb, offset, 4, mask);
1943         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1944                 tvb, offset, 4, mask);
1945         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1946                 tvb, offset, 4, mask);
1947         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1948                 tvb, offset, 4, mask);
1949         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1950                 tvb, offset, 4, mask);
1951         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1952                 tvb, offset, 4, mask);
1953         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1954                 tvb, offset, 4, mask);
1955
1956         return mask;
1957 }
1958
1959 #define RAWMODE_READ   0x01
1960 #define RAWMODE_WRITE  0x02
1961 static const true_false_string tfs_rm_read = {
1962         "Read Raw is supported",
1963         "Read Raw is not supported"
1964 };
1965 static const true_false_string tfs_rm_write = {
1966         "Write Raw is supported",
1967         "Write Raw is not supported"
1968 };
1969
1970 static int
1971 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1972 {
1973         guint16 mask;
1974         proto_item *item = NULL;
1975         proto_tree *tree = NULL;
1976
1977         mask = tvb_get_letohs(tvb, offset);
1978
1979         if(parent_tree){
1980                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1981                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1982         }
1983
1984         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
1985         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
1986
1987         offset += 2;
1988
1989         return offset;
1990 }
1991
1992 #define SECURITY_MODE_MODE             0x01
1993 #define SECURITY_MODE_PASSWORD         0x02
1994 #define SECURITY_MODE_SIGNATURES       0x04
1995 #define SECURITY_MODE_SIG_REQUIRED     0x08
1996 static const true_false_string tfs_sm_mode = {
1997         "USER security mode",
1998         "SHARE security mode"
1999 };
2000 static const true_false_string tfs_sm_password = {
2001         "ENCRYPTED password. Use challenge/response",
2002         "PLAINTEXT password"
2003 };
2004 static const true_false_string tfs_sm_signatures = {
2005         "Security signatures ENABLED",
2006         "Security signatures NOT enabled"
2007 };
2008 static const true_false_string tfs_sm_sig_required = {
2009         "Security signatures REQUIRED",
2010         "Security signatures NOT required"
2011 };
2012
2013 static int
2014 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
2015 {
2016         guint16 mask = 0;
2017         proto_item *item = NULL;
2018         proto_tree *tree = NULL;
2019
2020         switch(wc){
2021         case 13:
2022                 mask = tvb_get_letohs(tvb, offset);
2023                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2024                                 "Security Mode: 0x%04x", mask);
2025                 tree = proto_item_add_subtree(item, ett_smb_mode);
2026                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
2027                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
2028                 offset += 2;
2029                 break;
2030
2031         case 17:
2032                 mask = tvb_get_guint8(tvb, offset);
2033                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
2034                                 "Security Mode: 0x%02x", mask);
2035                 tree = proto_item_add_subtree(item, ett_smb_mode);
2036                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2037                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2038                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2039                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2040                 offset += 1;
2041                 break;
2042         }
2043
2044         return offset;
2045 }
2046
2047 static int
2048 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2049 {
2050         proto_item *it = NULL;
2051         proto_tree *tr = NULL;
2052         guint16 bc;
2053         guint8 wc;
2054
2055         WORD_COUNT;
2056
2057         BYTE_COUNT;
2058
2059         if(tree){
2060                 it = proto_tree_add_text(tree, tvb, offset, bc,
2061                                 "Requested Dialects");
2062                 tr = proto_item_add_subtree(it, ett_smb_dialects);
2063         }
2064
2065         while(bc){
2066                 int len;
2067                 const guint8 *str;
2068                 proto_item *dit = NULL;
2069                 proto_tree *dtr = NULL;
2070
2071                 /* XXX - what if this runs past bc? */
2072                 len = tvb_strsize(tvb, offset+1);
2073                 str = tvb_get_ptr(tvb, offset+1, len);
2074
2075                 if(tr){
2076                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2077                                         "Dialect: %s", str);
2078                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2079                 }
2080
2081                 /* Buffer Format */
2082                 CHECK_BYTE_COUNT(1);
2083                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2084                         TRUE);
2085                 COUNT_BYTES(1);
2086
2087                 /*Dialect Name */
2088                 CHECK_BYTE_COUNT(len);
2089                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2090                         len, str);
2091                 COUNT_BYTES(len);
2092         }
2093
2094         END_OF_SMB
2095
2096         return offset;
2097 }
2098
2099 static int
2100 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2101 {
2102         smb_info_t *si = pinfo->private_data;
2103         guint8 wc;
2104         guint16 dialect;
2105         const char *dn;
2106         int dn_len;
2107         guint16 bc;
2108         guint16 ekl=0;
2109         guint32 caps=0;
2110         gint16 tz;
2111
2112         WORD_COUNT;
2113
2114         /* Dialect Index */
2115         dialect = tvb_get_letohs(tvb, offset);
2116         switch(wc){
2117         case 1:
2118                 if(dialect==0xffff){
2119                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2120                                 tvb, offset, 2, dialect,
2121                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2122                 } else {
2123                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2124                                 tvb, offset, 2, dialect);
2125                 }
2126                 break;
2127         case 13:
2128                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2129                         tvb, offset, 2, dialect,
2130                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2131                 break;
2132         case 17:
2133                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2134                         tvb, offset, 2, dialect,
2135                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2136                 break;
2137         default:
2138                 proto_tree_add_text(tree, tvb, offset, wc*2,
2139                         "Words for unknown response format");
2140                 offset += wc*2;
2141                 goto bytecount;
2142         }
2143         offset += 2;
2144
2145         switch(wc){
2146         case 13:
2147                 /* Security Mode */
2148                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2149
2150                 /* Maximum Transmit Buffer Size */
2151                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2152                         tvb, offset, 2, TRUE);
2153                 offset += 2;
2154
2155                 /* Maximum Multiplex Count */
2156                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2157                         tvb, offset, 2, TRUE);
2158                 offset += 2;
2159
2160                 /* Maximum Vcs Number */
2161                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2162                         tvb, offset, 2, TRUE);
2163                 offset += 2;
2164
2165                 /* raw mode */
2166                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2167
2168                 /* session key */
2169                 proto_tree_add_item(tree, hf_smb_session_key,
2170                         tvb, offset, 4, TRUE);
2171                 offset += 4;
2172
2173                 /* current time and date at server */
2174                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2175                     TRUE);
2176
2177                 /* time zone */
2178                 tz = tvb_get_letohs(tvb, offset);
2179                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2180                 offset += 2;
2181
2182                 /* encryption key length */
2183                 ekl = tvb_get_letohs(tvb, offset);
2184                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2185                 offset += 2;
2186
2187                 /* 2 reserved bytes */
2188                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2189                 offset += 2;
2190
2191                 break;
2192
2193         case 17:
2194                 /* Security Mode */
2195                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2196
2197                 /* Maximum Multiplex Count */
2198                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2199                         tvb, offset, 2, TRUE);
2200                 offset += 2;
2201
2202                 /* Maximum Vcs Number */
2203                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2204                         tvb, offset, 2, TRUE);
2205                 offset += 2;
2206
2207                 /* Maximum Transmit Buffer Size */
2208                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2209                         tvb, offset, 4, TRUE);
2210                 offset += 4;
2211
2212                 /* maximum raw buffer size */
2213                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2214                         tvb, offset, 4, TRUE);
2215                 offset += 4;
2216
2217                 /* session key */
2218                 proto_tree_add_item(tree, hf_smb_session_key,
2219                         tvb, offset, 4, TRUE);
2220                 offset += 4;
2221
2222                 /* server capabilities */
2223                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2224                 offset += 4;
2225
2226                 /* system time */
2227                 offset = dissect_smb_64bit_time(tvb, tree, offset,
2228                                 hf_smb_system_time);
2229
2230                 /* time zone */
2231                 tz = tvb_get_letohs(tvb, offset);
2232                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2233                         tvb, offset, 2, tz,
2234                         "Server Time Zone: %d min from UTC", tz);
2235                 offset += 2;
2236
2237                 /* encryption key length */
2238                 ekl = tvb_get_guint8(tvb, offset);
2239                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2240                         tvb, offset, 1, ekl);
2241                 offset += 1;
2242
2243                 break;
2244         }
2245
2246         BYTE_COUNT;
2247
2248         switch(wc){
2249         case 13:
2250                 /* challenge/response encryption key */
2251                 if(ekl){
2252                         CHECK_BYTE_COUNT(ekl);
2253                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2254                         COUNT_BYTES(ekl);
2255                 }
2256
2257                 /*
2258                  * Primary domain.
2259                  *
2260                  * XXX - not present if negotiated dialect isn't
2261                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2262                  * have to see the request, or assume what dialect strings
2263                  * were sent, to determine that.
2264                  *
2265                  * Is this something other than a primary domain if the
2266                  * negotiated dialect is Windows for Workgroups 3.1a?
2267                  * It appears to be 8 bytes of binary data in at least
2268                  * one capture - is that an encryption key or something
2269                  * such as that?
2270                  */
2271                 dn = get_unicode_or_ascii_string(tvb, &offset,
2272                         si->unicode, &dn_len, FALSE, FALSE, &bc);
2273                 if (dn == NULL)
2274                         goto endofcommand;
2275                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2276                         offset, dn_len,dn);
2277                 COUNT_BYTES(dn_len);
2278                 break;
2279
2280         case 17:
2281                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2282                         /* challenge/response encryption key */
2283                         /* XXX - is this aligned on an even boundary? */
2284                         if(ekl){
2285                                 CHECK_BYTE_COUNT(ekl);
2286                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2287                                         tvb, offset, ekl, TRUE);
2288                                 COUNT_BYTES(ekl);
2289                         }
2290
2291                         /* domain */
2292                         /* this string is special, unicode is flagged in caps */
2293                         /* This string is NOT padded to be 16bit aligned.
2294                            (seen in actual capture)
2295                            XXX - I've seen a capture where it appears to be
2296                            so aligned, but I've also seen captures where
2297                            it is.  The captures where it appeared to be
2298                            aligned may have been from buggy servers. */
2299                         si->unicode = (caps&SERVER_CAP_UNICODE);
2300                         dn = get_unicode_or_ascii_string(tvb,
2301                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2302                                 &bc);
2303                         if (dn == NULL)
2304                                 goto endofcommand;
2305                         proto_tree_add_string(tree, hf_smb_primary_domain,
2306                                 tvb, offset, dn_len, dn);
2307                         COUNT_BYTES(dn_len);
2308
2309                         /* server name, seen in w2k pro capture */
2310                         dn = get_unicode_or_ascii_string(tvb,
2311                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2312                                 &bc);
2313                         if (dn == NULL)
2314                                 goto endofcommand;
2315                         proto_tree_add_string(tree, hf_smb_server,
2316                                 tvb, offset, dn_len, dn);
2317                         COUNT_BYTES(dn_len);
2318
2319                 } else {
2320                         proto_item *blob_item;
2321
2322                         /* guid */
2323                         /* XXX - show it in the standard Microsoft format
2324                            for GUIDs? */
2325                         CHECK_BYTE_COUNT(16);
2326                         proto_tree_add_item(tree, hf_smb_server_guid,
2327                                 tvb, offset, 16, TRUE);
2328                         COUNT_BYTES(16);
2329
2330                         blob_item = proto_tree_add_item(
2331                                 tree, hf_smb_security_blob,
2332                                 tvb, offset, bc, TRUE);
2333
2334                         /* security blob */
2335                         if(bc){
2336                                 tvbuff_t *gssapi_tvb;
2337                                 proto_tree *gssapi_tree;
2338
2339                                 gssapi_tree = proto_item_add_subtree(
2340                                         blob_item, ett_smb_gssapi);
2341
2342                                 gssapi_tvb = tvb_new_subset(
2343                                         tvb, offset, bc, bc);
2344
2345                                 call_dissector(
2346                                         gssapi_handle, gssapi_tvb, pinfo,
2347                                         gssapi_tree);
2348
2349                                 COUNT_BYTES(bc);
2350                         }
2351                 }
2352                 break;
2353         }
2354
2355         END_OF_SMB
2356
2357         return offset;
2358 }
2359
2360
2361 static int
2362 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2363 {
2364         smb_info_t *si = pinfo->private_data;
2365         int dn_len;
2366         const char *dn;
2367         guint8 wc;
2368         guint16 bc;
2369
2370         WORD_COUNT;
2371
2372         BYTE_COUNT;
2373
2374         /* buffer format */
2375         CHECK_BYTE_COUNT(1);
2376         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2377         COUNT_BYTES(1);
2378
2379         /* dir name */
2380         dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
2381                 FALSE, FALSE, &bc);
2382         if (dn == NULL)
2383                 goto endofcommand;
2384         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2385                 dn);
2386         COUNT_BYTES(dn_len);
2387
2388         if (check_col(pinfo->cinfo, COL_INFO)) {
2389                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s", dn);
2390         }
2391
2392         END_OF_SMB
2393
2394         return offset;
2395 }
2396
2397 static int
2398 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2399 {
2400         guint8 wc;
2401         guint16 bc;
2402
2403         WORD_COUNT;
2404
2405         BYTE_COUNT;
2406
2407         END_OF_SMB
2408
2409         return offset;
2410 }
2411
2412 static int
2413 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2414 {
2415         guint16 ec, bc;
2416         guint8 wc;
2417
2418         WORD_COUNT;
2419
2420         /* echo count */
2421         ec = tvb_get_letohs(tvb, offset);
2422         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2423         offset += 2;
2424
2425         BYTE_COUNT;
2426
2427         if (bc != 0) {
2428                 /* echo data */
2429                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2430                 COUNT_BYTES(bc);
2431         }
2432
2433         END_OF_SMB
2434
2435         return offset;
2436 }
2437
2438 static int
2439 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2440 {
2441         guint16 bc;
2442         guint8 wc;
2443
2444         WORD_COUNT;
2445
2446         /* echo sequence number */
2447         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2448         offset += 2;
2449
2450         BYTE_COUNT;
2451
2452         if (bc != 0) {
2453                 /* echo data */
2454                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2455                 COUNT_BYTES(bc);
2456         }
2457
2458         END_OF_SMB
2459
2460         return offset;
2461 }
2462
2463 static int
2464 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2465 {
2466         smb_info_t *si = pinfo->private_data;
2467         int an_len, pwlen;
2468         const char *an;
2469         guint8 wc;
2470         guint16 bc;
2471
2472         WORD_COUNT;
2473
2474         BYTE_COUNT;
2475
2476         /* buffer format */
2477         CHECK_BYTE_COUNT(1);
2478         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2479         COUNT_BYTES(1);
2480
2481         /* Path */
2482         an = get_unicode_or_ascii_string(tvb, &offset,
2483                 si->unicode, &an_len, FALSE, FALSE, &bc);
2484         if (an == NULL)
2485                 goto endofcommand;
2486         proto_tree_add_string(tree, hf_smb_path, tvb,
2487                 offset, an_len, an);
2488         COUNT_BYTES(an_len);
2489
2490         if (check_col(pinfo->cinfo, COL_INFO)) {
2491                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
2492         }
2493
2494         /* buffer format */
2495         CHECK_BYTE_COUNT(1);
2496         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2497         COUNT_BYTES(1);
2498
2499         /* password, ANSI */
2500         /* XXX - what if this runs past bc? */
2501         pwlen = tvb_strsize(tvb, offset);
2502         CHECK_BYTE_COUNT(pwlen);
2503         proto_tree_add_item(tree, hf_smb_password,
2504                 tvb, offset, pwlen, TRUE);
2505         COUNT_BYTES(pwlen);
2506
2507         /* buffer format */
2508         CHECK_BYTE_COUNT(1);
2509         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2510         COUNT_BYTES(1);
2511
2512         /* Service */
2513         an = get_unicode_or_ascii_string(tvb, &offset,
2514                 si->unicode, &an_len, FALSE, FALSE, &bc);
2515         if (an == NULL)
2516                 goto endofcommand;
2517         proto_tree_add_string(tree, hf_smb_service, tvb,
2518                 offset, an_len, an);
2519         COUNT_BYTES(an_len);
2520
2521         END_OF_SMB
2522
2523         return offset;
2524 }
2525
2526 static int
2527 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2528 {
2529         guint8 wc;
2530         guint16 bc;
2531
2532         WORD_COUNT;
2533
2534         /* Maximum Buffer Size */
2535         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2536         offset += 2;
2537
2538         /* tid */
2539         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2540         offset += 2;
2541
2542         BYTE_COUNT;
2543
2544         END_OF_SMB
2545
2546         return offset;
2547 }
2548
2549
2550 static const true_false_string tfs_of_create = {
2551         "Create file if it does not exist",
2552         "Fail if file does not exist"
2553 };
2554 static const value_string of_open[] = {
2555         { 0,            "Fail if file exists"},
2556         { 1,            "Open file if it exists"},
2557         { 2,            "Truncate file if it exists"},
2558         {0, NULL}
2559 };
2560 static int
2561 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2562 {
2563         guint16 mask;
2564         proto_item *item = NULL;
2565         proto_tree *tree = NULL;
2566
2567         mask = tvb_get_letohs(tvb, offset);
2568
2569         if(parent_tree){
2570                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2571                         "Open Function: 0x%04x", mask);
2572                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2573         }
2574
2575         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2576                 tvb, offset, 2, mask);
2577         proto_tree_add_uint(tree, hf_smb_open_function_open,
2578                 tvb, offset, 2, mask);
2579
2580         offset += 2;
2581
2582         return offset;
2583 }
2584
2585
2586 static const true_false_string tfs_mf_file = {
2587         "Target must be a file",
2588         "Target needn't be a file"
2589 };
2590 static const true_false_string tfs_mf_dir = {
2591         "Target must be a directory",
2592         "Target needn't be a directory"
2593 };
2594 static const true_false_string tfs_mf_verify = {
2595         "MUST verify all writes",
2596         "Don't have to verify writes"
2597 };
2598 static int
2599 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2600 {
2601         guint16 mask;
2602         proto_item *item = NULL;
2603         proto_tree *tree = NULL;
2604
2605         mask = tvb_get_letohs(tvb, offset);
2606
2607         if(parent_tree){
2608                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2609                         "Flags: 0x%04x", mask);
2610                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2611         }
2612
2613         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2614                 tvb, offset, 2, mask);
2615         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2616                 tvb, offset, 2, mask);
2617         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2618                 tvb, offset, 2, mask);
2619
2620         offset += 2;
2621
2622         return offset;
2623 }
2624
2625 static const true_false_string tfs_cf_mode = {
2626         "ASCII",
2627         "Binary"
2628 };
2629 static const true_false_string tfs_cf_tree_copy = {
2630         "Copy is a tree copy",
2631         "Copy is a file copy"
2632 };
2633 static const true_false_string tfs_cf_ea_action = {
2634         "Fail copy",
2635         "Discard EAs"
2636 };
2637 static int
2638 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2639 {
2640         guint16 mask;
2641         proto_item *item = NULL;
2642         proto_tree *tree = NULL;
2643
2644         mask = tvb_get_letohs(tvb, offset);
2645
2646         if(parent_tree){
2647                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2648                         "Flags: 0x%04x", mask);
2649                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2650         }
2651
2652         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
2653                 tvb, offset, 2, mask);
2654         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2655                 tvb, offset, 2, mask);
2656         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2657                 tvb, offset, 2, mask);
2658         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2659                 tvb, offset, 2, mask);
2660         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2661                 tvb, offset, 2, mask);
2662         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2663                 tvb, offset, 2, mask);
2664         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2665                 tvb, offset, 2, mask);
2666
2667         offset += 2;
2668
2669         return offset;
2670 }
2671
2672 static int
2673 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2674 {
2675         smb_info_t *si = pinfo->private_data;
2676         int fn_len;
2677         guint16 tid;
2678         guint16 bc;
2679         guint8 wc;
2680         const char *fn;
2681
2682         WORD_COUNT;
2683
2684         /* tid */
2685         tid = tvb_get_letohs(tvb, offset);
2686         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2687                 "TID (target): 0x%04x", tid);
2688         offset += 2;
2689
2690         /* open function */
2691         offset = dissect_open_function(tvb, tree, offset);
2692
2693         /* move flags */
2694         offset = dissect_move_flags(tvb, tree, offset);
2695
2696         BYTE_COUNT;
2697
2698         /* buffer format */
2699         CHECK_BYTE_COUNT(1);
2700         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2701         COUNT_BYTES(1);
2702
2703         /* file name */
2704         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2705                 FALSE, FALSE, &bc);
2706         if (fn == NULL)
2707                 goto endofcommand;
2708         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2709                 fn_len, fn, "Old File Name: %s", fn);
2710         COUNT_BYTES(fn_len);
2711
2712         if (check_col(pinfo->cinfo, COL_INFO)) {
2713                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2714         }
2715
2716         /* buffer format */
2717         CHECK_BYTE_COUNT(1);
2718         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2719         COUNT_BYTES(1);
2720
2721         /* file name */
2722         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2723                 FALSE, FALSE, &bc);
2724         if (fn == NULL)
2725                 goto endofcommand;
2726         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2727                 fn_len, fn, "New File Name: %s", fn);
2728         COUNT_BYTES(fn_len);
2729
2730         if (check_col(pinfo->cinfo, COL_INFO)) {
2731                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2732         }
2733
2734         END_OF_SMB
2735
2736         return offset;
2737 }
2738
2739 static int
2740 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2741 {
2742         smb_info_t *si = pinfo->private_data;
2743         int fn_len;
2744         guint16 tid;
2745         guint16 bc;
2746         guint8 wc;
2747         const char *fn;
2748
2749         WORD_COUNT;
2750
2751         /* tid */
2752         tid = tvb_get_letohs(tvb, offset);
2753         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2754                 "TID (target): 0x%04x", tid);
2755         offset += 2;
2756
2757         /* open function */
2758         offset = dissect_open_function(tvb, tree, offset);
2759
2760         /* copy flags */
2761         offset = dissect_copy_flags(tvb, tree, offset);
2762
2763         BYTE_COUNT;
2764
2765         /* buffer format */
2766         CHECK_BYTE_COUNT(1);
2767         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2768         COUNT_BYTES(1);
2769
2770         /* file name */
2771         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2772                 FALSE, FALSE, &bc);
2773         if (fn == NULL)
2774                 goto endofcommand;
2775         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2776                 fn_len, fn, "Source File Name: %s", fn);
2777         COUNT_BYTES(fn_len);
2778
2779         if (check_col(pinfo->cinfo, COL_INFO)) {
2780                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s", fn);
2781         }
2782
2783         /* buffer format */
2784         CHECK_BYTE_COUNT(1);
2785         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2786         COUNT_BYTES(1);
2787
2788         /* file name */
2789         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2790                 FALSE, FALSE, &bc);
2791         if (fn == NULL)
2792                 goto endofcommand;
2793         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2794                 fn_len, fn, "Destination File Name: %s", fn);
2795         COUNT_BYTES(fn_len);
2796
2797         if (check_col(pinfo->cinfo, COL_INFO)) {
2798                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", fn);
2799         }
2800
2801         END_OF_SMB
2802
2803         return offset;
2804 }
2805
2806 static int
2807 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2808 {
2809         smb_info_t *si = pinfo->private_data;
2810         int fn_len;
2811         const char *fn;
2812         guint8 wc;
2813         guint16 bc;
2814
2815         WORD_COUNT;
2816
2817         /* # of files moved */
2818         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
2819         offset += 2;
2820
2821         BYTE_COUNT;
2822
2823         /* buffer format */
2824         CHECK_BYTE_COUNT(1);
2825         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2826         COUNT_BYTES(1);
2827
2828         /* file name */
2829         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2830                 FALSE, FALSE, &bc);
2831         if (fn == NULL)
2832                 goto endofcommand;
2833         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2834                 fn);
2835         COUNT_BYTES(fn_len);
2836
2837         END_OF_SMB
2838
2839         return offset;
2840 }
2841
2842 static int
2843 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2844 {
2845         smb_info_t *si = pinfo->private_data;
2846         int fn_len;
2847         const char *fn;
2848         guint8 wc;
2849         guint16 bc;
2850
2851         WORD_COUNT;
2852
2853         /* desired access */
2854         offset = dissect_access(tvb, tree, offset, "Desired");
2855
2856         /* Search Attributes */
2857         offset = dissect_search_attributes(tvb, tree, offset);
2858
2859         BYTE_COUNT;
2860
2861         /* buffer format */
2862         CHECK_BYTE_COUNT(1);
2863         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2864         COUNT_BYTES(1);
2865
2866         /* file name */
2867         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2868                 FALSE, FALSE, &bc);
2869         if (fn == NULL)
2870                 goto endofcommand;
2871         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2872                 fn);
2873         COUNT_BYTES(fn_len);
2874
2875         if (check_col(pinfo->cinfo, COL_INFO)) {
2876                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2877         }
2878
2879         END_OF_SMB
2880
2881         return offset;
2882 }
2883
2884 void
2885 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2886     int len, guint16 fid)
2887 {
2888         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2889         if (check_col(pinfo->cinfo, COL_INFO))
2890                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2891 }
2892
2893 static int
2894 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2895 {
2896         guint8 wc;
2897         guint16 bc;
2898         guint16 fid;
2899
2900         WORD_COUNT;
2901
2902         /* fid */
2903         fid = tvb_get_letohs(tvb, offset);
2904         add_fid(tvb, pinfo, tree, offset, 2, fid);
2905         offset += 2;
2906
2907         /* File Attributes */
2908         offset = dissect_file_attributes(tvb, tree, offset);
2909
2910         /* last write time */
2911         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2912
2913         /* File Size */
2914         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2915         offset += 4;
2916
2917         /* granted access */
2918         offset = dissect_access(tvb, tree, offset, "Granted");
2919
2920         BYTE_COUNT;
2921
2922         END_OF_SMB
2923
2924         return offset;
2925 }
2926
2927 static int
2928 dissect_fid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2929 {
2930         guint8 wc;
2931         guint16 bc;
2932         guint16 fid;
2933
2934         WORD_COUNT;
2935
2936         /* fid */
2937         fid = tvb_get_letohs(tvb, offset);
2938         add_fid(tvb, pinfo, tree, offset, 2, fid);
2939         offset += 2;
2940
2941         BYTE_COUNT;
2942
2943         END_OF_SMB
2944
2945         return offset;
2946 }
2947
2948 static int
2949 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2950 {
2951         smb_info_t *si = pinfo->private_data;
2952         int fn_len;
2953         const char *fn;
2954         guint8 wc;
2955         guint16 bc;
2956
2957         WORD_COUNT;
2958
2959         /* file attributes */
2960         offset = dissect_file_attributes(tvb, tree, offset);
2961
2962         /* creation time */
2963         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
2964
2965         BYTE_COUNT;
2966
2967         /* buffer format */
2968         CHECK_BYTE_COUNT(1);
2969         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2970         COUNT_BYTES(1);
2971
2972         /* File Name */
2973         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2974                 FALSE, FALSE, &bc);
2975         if (fn == NULL)
2976                 goto endofcommand;
2977         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2978                 fn);
2979         COUNT_BYTES(fn_len);
2980
2981         if (check_col(pinfo->cinfo, COL_INFO)) {
2982                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2983         }
2984
2985         END_OF_SMB
2986
2987         return offset;
2988 }
2989
2990 static int
2991 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2992 {
2993         guint8 wc;
2994         guint16 bc, fid;
2995
2996         WORD_COUNT;
2997
2998         /* fid */
2999         fid = tvb_get_letohs(tvb, offset);
3000         add_fid(tvb, pinfo, tree, offset, 2, fid);
3001         offset += 2;
3002
3003         /* last write time */
3004         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3005
3006         BYTE_COUNT;
3007
3008         END_OF_SMB
3009
3010         return offset;
3011 }
3012
3013 static int
3014 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3015 {
3016         smb_info_t *si = pinfo->private_data;
3017         int fn_len;
3018         const char *fn;
3019         guint8 wc;
3020         guint16 bc;
3021
3022         WORD_COUNT;
3023
3024         /* search attributes */
3025         offset = dissect_search_attributes(tvb, tree, offset);
3026
3027         BYTE_COUNT;
3028
3029         /* buffer format */
3030         CHECK_BYTE_COUNT(1);
3031         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3032         COUNT_BYTES(1);
3033
3034         /* file name */
3035         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3036                 FALSE, FALSE, &bc);
3037         if (fn == NULL)
3038                 goto endofcommand;
3039         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3040                 fn);
3041         COUNT_BYTES(fn_len);
3042
3043         if (check_col(pinfo->cinfo, COL_INFO)) {
3044                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3045         }
3046
3047         END_OF_SMB
3048
3049         return offset;
3050 }
3051
3052 static int
3053 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3054 {
3055         smb_info_t *si = pinfo->private_data;
3056         int fn_len;
3057         const char *fn;
3058         guint8 wc;
3059         guint16 bc;
3060
3061         WORD_COUNT;
3062
3063         /* search attributes */
3064         offset = dissect_search_attributes(tvb, tree, offset);
3065
3066         BYTE_COUNT;
3067
3068         /* buffer format */
3069         CHECK_BYTE_COUNT(1);
3070         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3071         COUNT_BYTES(1);
3072
3073         /* old file name */
3074         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3075                 FALSE, FALSE, &bc);
3076         if (fn == NULL)
3077                 goto endofcommand;
3078         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3079                 fn);
3080         COUNT_BYTES(fn_len);
3081
3082         if (check_col(pinfo->cinfo, COL_INFO)) {
3083                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3084         }
3085
3086         /* buffer format */
3087         CHECK_BYTE_COUNT(1);
3088         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3089         COUNT_BYTES(1);
3090
3091         /* file name */
3092         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3093                 FALSE, FALSE, &bc);
3094         if (fn == NULL)
3095                 goto endofcommand;
3096         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3097                 fn);
3098         COUNT_BYTES(fn_len);
3099
3100         if (check_col(pinfo->cinfo, COL_INFO)) {
3101                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3102         }
3103
3104         END_OF_SMB
3105
3106         return offset;
3107 }
3108
3109 static int
3110 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3111 {
3112         smb_info_t *si = pinfo->private_data;
3113         int fn_len;
3114         const char *fn;
3115         guint8 wc;
3116         guint16 bc;
3117
3118         WORD_COUNT;
3119
3120         /* search attributes */
3121         offset = dissect_search_attributes(tvb, tree, offset);
3122
3123         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3124         offset += 2;
3125
3126         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3127         offset += 4;
3128
3129         BYTE_COUNT;
3130
3131         /* buffer format */
3132         CHECK_BYTE_COUNT(1);
3133         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3134         COUNT_BYTES(1);
3135
3136         /* old file name */
3137         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3138                 FALSE, FALSE, &bc);
3139         if (fn == NULL)
3140                 goto endofcommand;
3141         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3142                 fn);
3143         COUNT_BYTES(fn_len);
3144
3145         if (check_col(pinfo->cinfo, COL_INFO)) {
3146                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3147         }
3148
3149         /* buffer format */
3150         CHECK_BYTE_COUNT(1);
3151         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3152         COUNT_BYTES(1);
3153
3154         /* file name */
3155         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3156                 FALSE, FALSE, &bc);
3157         if (fn == NULL)
3158                 goto endofcommand;
3159         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3160                 fn);
3161         COUNT_BYTES(fn_len);
3162
3163         if (check_col(pinfo->cinfo, COL_INFO)) {
3164                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3165         }
3166
3167         END_OF_SMB
3168
3169         return offset;
3170 }
3171
3172
3173 static int
3174 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3175 {
3176         smb_info_t *si = pinfo->private_data;
3177         guint16 bc;
3178         guint8 wc;
3179         const char *fn;
3180         int fn_len;
3181
3182         WORD_COUNT;
3183
3184         BYTE_COUNT;
3185
3186         /* Buffer Format */
3187         CHECK_BYTE_COUNT(1);
3188         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3189         COUNT_BYTES(1);
3190
3191         /* File Name */
3192         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3193                 FALSE, FALSE, &bc);
3194         if (fn == NULL)
3195                 goto endofcommand;
3196         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3197                 fn);
3198         COUNT_BYTES(fn_len);
3199
3200         if (check_col(pinfo->cinfo, COL_INFO)) {
3201                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3202         }
3203
3204         END_OF_SMB
3205
3206         return offset;
3207 }
3208
3209 static int
3210 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3211 {
3212         guint16 bc;
3213         guint8 wc;
3214
3215         WORD_COUNT;
3216
3217         /* File Attributes */
3218         offset = dissect_file_attributes(tvb, tree, offset);
3219
3220         /* Last Write Time */
3221         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3222
3223         /* File Size */
3224         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3225         offset += 4;
3226
3227         /* 10 reserved bytes */
3228         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3229         offset += 10;
3230
3231         BYTE_COUNT;
3232
3233         END_OF_SMB
3234
3235         return offset;
3236 }
3237
3238 static int
3239 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3240 {
3241         smb_info_t *si = pinfo->private_data;
3242         int fn_len;
3243         const char *fn;
3244         guint8 wc;
3245         guint16 bc;
3246
3247         WORD_COUNT;
3248
3249         /* file attributes */
3250         offset = dissect_file_attributes(tvb, tree, offset);
3251
3252         /* last write time */
3253         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3254
3255         /* 10 reserved bytes */
3256         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3257         offset += 10;
3258
3259         BYTE_COUNT;
3260
3261         /* buffer format */
3262         CHECK_BYTE_COUNT(1);
3263         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3264         COUNT_BYTES(1);
3265
3266         /* file name */
3267         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3268                 FALSE, FALSE, &bc);
3269         if (fn == NULL)
3270                 goto endofcommand;
3271         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3272                 fn);
3273         COUNT_BYTES(fn_len);
3274
3275         if (check_col(pinfo->cinfo, COL_INFO)) {
3276                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3277         }
3278
3279         END_OF_SMB
3280
3281         return offset;
3282 }
3283
3284 static int
3285 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3286 {
3287         guint8 wc;
3288         guint16 bc;
3289         smb_info_t *si;
3290         unsigned int fid;
3291
3292         WORD_COUNT;
3293
3294         /* fid */
3295         fid = tvb_get_letohs(tvb, offset);
3296         add_fid(tvb, pinfo, tree, offset, 2, fid);
3297         offset += 2;
3298         if (!pinfo->fd->flags.visited) {
3299                 /* remember the FID for the processing of the response */
3300                 si = (smb_info_t *)pinfo->private_data;
3301                 si->sip->extra_info=(void *)fid;
3302         }
3303
3304         /* read count */
3305         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3306         offset += 2;
3307
3308         /* offset */
3309         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3310         offset += 4;
3311
3312         /* remaining */
3313         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3314         offset += 2;
3315
3316         BYTE_COUNT;
3317
3318         END_OF_SMB
3319
3320         return offset;
3321 }
3322
3323 int
3324 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3325 {
3326         int tvblen;
3327
3328         if(bc>datalen){
3329                 /* We have some initial padding bytes. */
3330                 /* XXX - use the data offset here instead? */
3331                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3332                         TRUE);
3333                 offset += bc-datalen;
3334                 bc = datalen;
3335         }
3336         tvblen = tvb_length_remaining(tvb, offset);
3337         if(bc>tvblen){
3338                 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);
3339                 offset += tvblen;
3340         } else {
3341                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3342                 offset += bc;
3343         }
3344         return offset;
3345 }
3346
3347 static int
3348 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3349     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
3350 {
3351         int tvblen;
3352         tvbuff_t *dcerpc_tvb;
3353
3354         if(bc>datalen){
3355                 /* We have some initial padding bytes. */
3356                 /* XXX - use the data offset here instead? */
3357                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3358                         TRUE);
3359                 offset += bc-datalen;
3360                 bc = datalen;
3361         }
3362         tvblen = tvb_length_remaining(tvb, offset);
3363         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
3364         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
3365         if(bc>tvblen)
3366                 offset += tvblen;
3367         else
3368                 offset += bc;
3369         return offset;
3370 }
3371
3372 static int
3373 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3374 {
3375         guint16 cnt=0, bc;
3376         guint8 wc;
3377         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3378         int fid=0;
3379
3380         WORD_COUNT;
3381
3382         /* read count */
3383         cnt = tvb_get_letohs(tvb, offset);
3384         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3385         offset += 2;
3386
3387         /* 8 reserved bytes */
3388         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3389         offset += 8;
3390
3391         /* If we have seen the request, then print which FID this refers to */
3392         /* first check if we have seen the request */
3393         if(si->sip != NULL && si->sip->frame_req>0){
3394                 fid=(int)si->sip->extra_info;
3395                 add_fid(tvb, pinfo, tree, 0, 0, fid);
3396         }
3397
3398         BYTE_COUNT;
3399
3400         /* buffer format */
3401         CHECK_BYTE_COUNT(1);
3402         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3403         COUNT_BYTES(1);
3404
3405         /* data len */
3406         CHECK_BYTE_COUNT(2);
3407         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3408         COUNT_BYTES(2);
3409
3410         /* another way to transport DCERPC over SMB is to skip Transaction completely and just
3411            read write */
3412         if(bc){
3413                 if(si->sip != NULL && si->sip->flags&SMB_SIF_TID_IS_IPC){
3414                         /* dcerpc call */
3415                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
3416                             top_tree, offset, bc, bc, fid);
3417                 } else {
3418                         /* ordinary file data, or we didn't see the request,
3419                            so we don't know whether this is a DCERPC call
3420                            or not */
3421                         offset = dissect_file_data(tvb, tree, offset, bc, bc);
3422                 }
3423                 bc = 0;
3424         }
3425
3426         END_OF_SMB
3427
3428         return offset;
3429 }
3430
3431 static int
3432 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3433 {
3434         guint16 cnt, bc;
3435         guint8 wc;
3436
3437         WORD_COUNT;
3438
3439         /* read count */
3440         cnt = tvb_get_letohs(tvb, offset);
3441         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3442         offset += 2;
3443
3444         /* 8 reserved bytes */
3445         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3446         offset += 8;
3447
3448         BYTE_COUNT;
3449
3450         /* buffer format */
3451         CHECK_BYTE_COUNT(1);
3452         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3453         COUNT_BYTES(1);
3454
3455         /* data len */
3456         CHECK_BYTE_COUNT(2);
3457         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3458         COUNT_BYTES(2);
3459
3460         END_OF_SMB
3461
3462         return offset;
3463 }
3464
3465
3466 static int
3467 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3468 {
3469         guint32 ofs=0;
3470         guint16 cnt=0, bc, fid=0;
3471         guint8 wc;
3472         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3473
3474         WORD_COUNT;
3475
3476         /* fid */
3477         fid = tvb_get_letohs(tvb, offset);
3478         add_fid(tvb, pinfo, tree, offset, 2, fid);
3479         offset += 2;
3480
3481         /* write count */
3482         cnt = tvb_get_letohs(tvb, offset);
3483         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3484         offset += 2;
3485
3486         /* offset */
3487         ofs = tvb_get_letohl(tvb, offset);
3488         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3489         offset += 4;
3490
3491         if (check_col(pinfo->cinfo, COL_INFO))
3492                 col_append_fstr(pinfo->cinfo, COL_INFO,
3493                                 ", %u byte%s at offset %u", cnt,
3494                                 (cnt == 1) ? "" : "s", ofs);
3495
3496         /* remaining */
3497         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3498         offset += 2;
3499
3500         BYTE_COUNT;
3501
3502         /* buffer format */
3503         CHECK_BYTE_COUNT(1);
3504         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3505         COUNT_BYTES(1);
3506
3507         /* data len */
3508         CHECK_BYTE_COUNT(2);
3509         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3510         COUNT_BYTES(2);
3511
3512         if (bc != 0) {
3513                 if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
3514                         /* dcerpc call */
3515                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
3516                             top_tree, offset, bc, bc, fid);
3517                 } else {
3518                         /* ordinary file data */
3519                         offset = dissect_file_data(tvb, tree, offset, bc, bc);
3520                 }
3521                 bc = 0;
3522         }
3523
3524         END_OF_SMB
3525
3526         return offset;
3527 }
3528
3529 static int
3530 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3531 {
3532         guint8 wc;
3533         guint16 bc, cnt;
3534
3535         WORD_COUNT;
3536
3537         /* write count */
3538         cnt = tvb_get_letohs(tvb, offset);
3539         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3540         offset += 2;
3541
3542         if (check_col(pinfo->cinfo, COL_INFO))
3543                 col_append_fstr(pinfo->cinfo, COL_INFO,
3544                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
3545
3546         BYTE_COUNT;
3547
3548         END_OF_SMB
3549
3550         return offset;
3551 }
3552
3553 static int
3554 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3555 {
3556         guint8 wc;
3557         guint16 bc, fid;
3558
3559         WORD_COUNT;
3560
3561         /* fid */
3562         fid = tvb_get_letohs(tvb, offset);
3563         add_fid(tvb, pinfo, tree, offset, 2, fid);
3564         offset += 2;
3565
3566         /* lock count */
3567         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3568         offset += 4;
3569
3570         /* offset */
3571         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3572         offset += 4;
3573
3574         BYTE_COUNT;
3575
3576         END_OF_SMB
3577
3578         return offset;
3579 }
3580
3581 static int
3582 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3583 {
3584         smb_info_t *si = pinfo->private_data;
3585         int fn_len;
3586         const char *fn;
3587         guint8 wc;
3588         guint16 bc;
3589
3590         WORD_COUNT;
3591
3592         /* 2 reserved bytes */
3593         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3594         offset += 2;
3595
3596         /* Creation time */
3597         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3598
3599         BYTE_COUNT;
3600
3601         /* buffer format */
3602         CHECK_BYTE_COUNT(1);
3603         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3604         COUNT_BYTES(1);
3605
3606         /* directory name */
3607         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3608                 FALSE, FALSE, &bc);
3609         if (fn == NULL)
3610                 goto endofcommand;
3611         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3612                 fn);
3613         COUNT_BYTES(fn_len);
3614
3615         if (check_col(pinfo->cinfo, COL_INFO)) {
3616                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3617         }
3618
3619         END_OF_SMB
3620
3621         return offset;
3622 }
3623
3624 static int
3625 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3626 {
3627         smb_info_t *si = pinfo->private_data;
3628         int fn_len;
3629         const char *fn;
3630         guint8 wc;
3631         guint16 bc, fid;
3632
3633         WORD_COUNT;
3634
3635         /* fid */
3636         fid = tvb_get_letohs(tvb, offset);
3637         add_fid(tvb, pinfo, tree, offset, 2, fid);
3638         offset += 2;
3639
3640         BYTE_COUNT;
3641
3642         /* buffer format */
3643         CHECK_BYTE_COUNT(1);
3644         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3645         COUNT_BYTES(1);
3646
3647         /* file name */
3648         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3649                 FALSE, FALSE, &bc);
3650         if (fn == NULL)
3651                 goto endofcommand;
3652         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3653                 fn);
3654         COUNT_BYTES(fn_len);
3655
3656         END_OF_SMB
3657
3658         return offset;
3659 }
3660
3661 static const value_string seek_mode_vals[] = {
3662         {0,     "From Start Of File"},
3663         {1,     "From Current Position"},
3664         {2,     "From End Of File"},
3665         {0,     NULL}
3666 };
3667
3668 static int
3669 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3670 {
3671         guint8 wc;
3672         guint16 bc, fid;
3673
3674         WORD_COUNT;
3675
3676         /* fid */
3677         fid = tvb_get_letohs(tvb, offset);
3678         add_fid(tvb, pinfo, tree, offset, 2, fid);
3679         offset += 2;
3680
3681         /* Seek Mode */
3682         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3683         offset += 2;
3684
3685         /* offset */
3686         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3687         offset += 4;
3688
3689         BYTE_COUNT;
3690
3691         END_OF_SMB
3692
3693         return offset;
3694 }
3695
3696 static int
3697 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3698 {
3699         guint8 wc;
3700         guint16 bc;
3701
3702         WORD_COUNT;
3703
3704         /* offset */
3705         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3706         offset += 4;
3707
3708         BYTE_COUNT;
3709
3710         END_OF_SMB
3711
3712         return offset;
3713 }
3714
3715 static int
3716 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3717 {
3718         guint8 wc;
3719         guint16 bc, fid;
3720
3721         WORD_COUNT;
3722
3723         /* fid */
3724         fid = tvb_get_letohs(tvb, offset);
3725         add_fid(tvb, pinfo, tree, offset, 2, fid);
3726         offset += 2;
3727
3728         /* create time */
3729         offset = dissect_smb_datetime(tvb, tree, offset,
3730                 hf_smb_create_time,
3731                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3732
3733         /* access time */
3734         offset = dissect_smb_datetime(tvb, tree, offset,
3735                 hf_smb_access_time,
3736                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3737
3738         /* last write time */
3739         offset = dissect_smb_datetime(tvb, tree, offset,
3740                 hf_smb_last_write_time,
3741                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3742
3743         BYTE_COUNT;
3744
3745         END_OF_SMB
3746
3747         return offset;
3748 }
3749
3750 static int
3751 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3752 {
3753         guint8 wc;
3754         guint16 bc;
3755
3756         WORD_COUNT;
3757
3758         /* create time */
3759         offset = dissect_smb_datetime(tvb, tree, offset,
3760                 hf_smb_create_time,
3761                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3762
3763         /* access time */
3764         offset = dissect_smb_datetime(tvb, tree, offset,
3765                 hf_smb_access_time,
3766                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3767
3768         /* last write time */
3769         offset = dissect_smb_datetime(tvb, tree, offset,
3770                 hf_smb_last_write_time,
3771                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3772
3773         /* data size */
3774         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3775         offset += 4;
3776
3777         /* allocation size */
3778         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3779         offset += 4;
3780
3781         /* File Attributes */
3782         offset = dissect_file_attributes(tvb, tree, offset);
3783
3784         BYTE_COUNT;
3785
3786         END_OF_SMB
3787
3788         return offset;
3789 }
3790
3791 static int
3792 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3793 {
3794         guint8 wc;
3795         guint16 cnt=0;
3796         guint16 bc, fid;
3797
3798         WORD_COUNT;
3799
3800         /* fid */
3801         fid = tvb_get_letohs(tvb, offset);
3802         add_fid(tvb, pinfo, tree, offset, 2, fid);
3803         offset += 2;
3804
3805         /* write count */
3806         cnt = tvb_get_letohs(tvb, offset);
3807         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3808         offset += 2;
3809
3810         /* offset */
3811         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3812         offset += 4;
3813
3814         /* last write time */
3815         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3816
3817         if(wc==12){
3818                 /* 12 reserved bytes */
3819                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3820                 offset += 12;
3821         }
3822
3823         BYTE_COUNT;
3824
3825         /* 1 pad byte */
3826         CHECK_BYTE_COUNT(1);
3827         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3828         COUNT_BYTES(1);
3829
3830         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
3831         bc = 0; /* XXX */
3832
3833         END_OF_SMB
3834
3835         return offset;
3836 }
3837
3838 static int
3839 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3840 {
3841         guint8 wc;
3842         guint16 bc;
3843
3844         WORD_COUNT;
3845
3846         /* write count */
3847         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3848         offset += 2;
3849
3850         BYTE_COUNT;
3851
3852         END_OF_SMB
3853
3854         return offset;
3855 }
3856
3857 static int
3858 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3859 {
3860         guint8 wc;
3861         guint16 bc, fid;
3862         guint32 to;
3863
3864         WORD_COUNT;
3865
3866         /* fid */
3867         fid = tvb_get_letohs(tvb, offset);
3868         add_fid(tvb, pinfo, tree, offset, 2, fid);
3869         offset += 2;
3870
3871         /* offset */
3872         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3873         offset += 4;
3874
3875         /* max count */
3876         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3877         offset += 2;
3878
3879         /* min count */
3880         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3881         offset += 2;
3882
3883         /* timeout */
3884         to = tvb_get_letohl(tvb, offset);
3885         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3886         offset += 4;
3887
3888         /* 2 reserved bytes */
3889         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3890         offset += 2;
3891
3892         if(wc==10){
3893                 /* high offset */
3894                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3895                 offset += 4;
3896         }
3897
3898         BYTE_COUNT;
3899
3900         END_OF_SMB
3901
3902         return offset;
3903 }
3904
3905 static int
3906 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3907 {
3908         guint8 wc;
3909         guint16 bc;
3910
3911         WORD_COUNT;
3912
3913         /* units */
3914         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3915         offset += 2;
3916
3917         /* bpu */
3918         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3919         offset += 2;
3920
3921         /* block size */
3922         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3923         offset += 2;
3924
3925         /* free units */
3926         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3927         offset += 2;
3928
3929         /* 2 reserved bytes */
3930         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3931         offset += 2;
3932
3933         BYTE_COUNT;
3934
3935         END_OF_SMB
3936
3937         return offset;
3938 }
3939
3940 static int
3941 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3942 {
3943         guint8 wc;
3944         guint16 bc, fid;
3945
3946         WORD_COUNT;
3947
3948         /* fid */
3949         fid = tvb_get_letohs(tvb, offset);
3950         add_fid(tvb, pinfo, tree, offset, 2, fid);
3951         offset += 2;
3952
3953         /* offset */
3954         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3955         offset += 4;
3956
3957         /* max count */
3958         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3959         offset += 2;
3960
3961         /* min count */
3962         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3963         offset += 2;
3964
3965         /* 6 reserved bytes */
3966         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
3967         offset += 6;
3968
3969         BYTE_COUNT;
3970
3971         END_OF_SMB
3972
3973         return offset;
3974 }
3975
3976 static int
3977 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3978 {
3979         guint16 datalen=0, bc;
3980         guint8 wc;
3981
3982         WORD_COUNT;
3983
3984         /* offset */
3985         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3986         offset += 4;
3987
3988         /* count */
3989         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3990         offset += 2;
3991
3992         /* 2 reserved bytes */
3993         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3994         offset += 2;
3995
3996         /* data compaction mode */
3997         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
3998         offset += 2;
3999
4000         /* 2 reserved bytes */
4001         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4002         offset += 2;
4003
4004         /* data len */
4005         datalen = tvb_get_letohs(tvb, offset);
4006         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4007         offset += 2;
4008
4009         /* data offset */
4010         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4011         offset += 2;
4012
4013         BYTE_COUNT;
4014
4015         /* file data */
4016         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4017         bc = 0;
4018
4019         END_OF_SMB
4020
4021         return offset;
4022 }
4023
4024
4025 static const true_false_string tfs_write_mode_write_through = {
4026         "WRITE THROUGH requested",
4027         "Write through not requested"
4028 };
4029 static const true_false_string tfs_write_mode_return_remaining = {
4030         "RETURN REMAINING (pipe/dev) requested",
4031         "DON'T return remaining (pipe/dev)"
4032 };
4033 static const true_false_string tfs_write_mode_raw = {
4034         "Use WriteRawNamedPipe (pipe)",
4035         "DON'T use WriteRawNamedPipe (pipe)"
4036 };
4037 static const true_false_string tfs_write_mode_message_start = {
4038         "This is the START of a MESSAGE (pipe)",
4039         "This is NOT the start of a message (pipe)"
4040 };
4041 static const true_false_string tfs_write_mode_connectionless = {
4042         "CONNECTIONLESS mode requested",
4043         "Connectionless mode NOT requested"
4044 };
4045 static int
4046 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4047 {
4048         guint16 mask;
4049         proto_item *item = NULL;
4050         proto_tree *tree = NULL;
4051
4052         mask = tvb_get_letohs(tvb, offset);
4053
4054         if(parent_tree){
4055                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4056                         "Write Mode: 0x%04x", mask);
4057                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
4058         }
4059
4060         if(bm&0x0080){
4061                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
4062                         tvb, offset, 2, mask);
4063         }
4064         if(bm&0x0008){
4065                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
4066                         tvb, offset, 2, mask);
4067         }
4068         if(bm&0x0004){
4069                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
4070                         tvb, offset, 2, mask);
4071         }
4072         if(bm&0x0002){
4073                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
4074                         tvb, offset, 2, mask);
4075         }
4076         if(bm&0x0001){
4077                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4078                         tvb, offset, 2, mask);
4079         }
4080
4081         offset += 2;
4082         return offset;
4083 }
4084
4085 static int
4086 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4087 {
4088         guint32 to;
4089         guint16 datalen=0, bc, fid;
4090         guint8 wc;
4091
4092         WORD_COUNT;
4093
4094         /* fid */
4095         fid = tvb_get_letohs(tvb, offset);
4096         add_fid(tvb, pinfo, tree, offset, 2, fid);
4097         offset += 2;
4098
4099         /* total data length */
4100         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4101         offset += 2;
4102
4103         /* 2 reserved bytes */
4104         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4105         offset += 2;
4106
4107         /* offset */
4108         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4109         offset += 4;
4110
4111         /* timeout */
4112         to = tvb_get_letohl(tvb, offset);
4113         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4114         offset += 4;
4115
4116         /* mode */
4117         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4118
4119         /* 4 reserved bytes */
4120         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4121         offset += 4;
4122
4123         /* data len */
4124         datalen = tvb_get_letohs(tvb, offset);
4125         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4126         offset += 2;
4127
4128         /* data offset */
4129         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4130         offset += 2;
4131
4132         BYTE_COUNT;
4133
4134         /* file data */
4135         /* XXX - use the data offset to determine where the data starts? */
4136         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4137         bc = 0;
4138
4139         END_OF_SMB
4140
4141         return offset;
4142 }
4143
4144 static int
4145 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4146 {
4147         guint8 wc;
4148         guint16 bc;
4149
4150         WORD_COUNT;
4151
4152         /* remaining */
4153         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4154         offset += 2;
4155
4156         BYTE_COUNT;
4157
4158         END_OF_SMB
4159
4160         return offset;
4161 }
4162
4163 static int
4164 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4165 {
4166         guint32 to;
4167         guint16 datalen=0, bc, fid;
4168         guint8 wc;
4169
4170         WORD_COUNT;
4171
4172         /* fid */
4173         fid = tvb_get_letohs(tvb, offset);
4174         add_fid(tvb, pinfo, tree, offset, 2, fid);
4175         offset += 2;
4176
4177         /* total data length */
4178         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4179         offset += 2;
4180
4181         /* 2 reserved bytes */
4182         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4183         offset += 2;
4184
4185         /* offset */
4186         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4187         offset += 4;
4188
4189         /* timeout */
4190         to = tvb_get_letohl(tvb, offset);
4191         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4192         offset += 4;
4193
4194         /* mode */
4195         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
4196
4197         /* request mask */
4198         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
4199         offset += 4;
4200
4201         /* data len */
4202         datalen = tvb_get_letohs(tvb, offset);
4203         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4204         offset += 2;
4205
4206         /* data offset */
4207         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4208         offset += 2;
4209
4210         BYTE_COUNT;
4211
4212         /* file data */
4213         /* XXX - use the data offset to determine where the data starts? */
4214         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4215         bc = 0;
4216
4217         END_OF_SMB
4218
4219         return offset;
4220 }
4221
4222 static int
4223 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4224 {
4225         guint8 wc;
4226         guint16 bc;
4227
4228         WORD_COUNT;
4229
4230         /* response mask */
4231         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
4232         offset += 4;
4233
4234         BYTE_COUNT;
4235
4236         END_OF_SMB
4237
4238         return offset;
4239 }
4240
4241 static int
4242 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4243 {
4244         guint8 wc;
4245         guint16 bc;
4246
4247         WORD_COUNT;
4248
4249         /* sid */
4250         proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
4251         offset += 2;
4252
4253         BYTE_COUNT;
4254
4255         END_OF_SMB
4256
4257         return offset;
4258 }
4259
4260 static int
4261 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
4262     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4263     gboolean has_find_id)
4264 {
4265         proto_item *item = NULL;
4266         proto_tree *tree = NULL;
4267         smb_info_t *si = pinfo->private_data;
4268         int fn_len;
4269         const char *fn;
4270         char fname[11+1];
4271
4272         if(parent_tree){
4273                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
4274                         "Resume Key");
4275                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
4276         }
4277
4278         /* reserved byte */
4279         CHECK_BYTE_COUNT_SUBR(1);
4280         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4281         COUNT_BYTES_SUBR(1);
4282
4283         /* file name */
4284         fn_len = 11;
4285         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4286                 TRUE, TRUE, bcp);
4287         CHECK_STRING_SUBR(fn);
4288         /* ensure that it's null-terminated */
4289         strncpy(fname, fn, 11);
4290         fname[11] = '\0';
4291         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
4292                 fname);
4293         COUNT_BYTES_SUBR(fn_len);
4294
4295         if (has_find_id) {
4296                 CHECK_BYTE_COUNT_SUBR(1);
4297                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
4298                 COUNT_BYTES_SUBR(1);
4299
4300                 /* server cookie */
4301                 CHECK_BYTE_COUNT_SUBR(4);
4302                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
4303                 COUNT_BYTES_SUBR(4);
4304         } else {
4305                 /* server cookie */
4306                 CHECK_BYTE_COUNT_SUBR(5);
4307                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
4308                 COUNT_BYTES_SUBR(5);
4309         }
4310
4311         /* client cookie */
4312         CHECK_BYTE_COUNT_SUBR(4);
4313         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
4314         COUNT_BYTES_SUBR(4);
4315
4316         *trunc = FALSE;
4317         return offset;
4318 }
4319
4320 static int
4321 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
4322     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4323     gboolean has_find_id)
4324 {
4325         proto_item *item = NULL;
4326         proto_tree *tree = NULL;
4327         smb_info_t *si = pinfo->private_data;
4328         int fn_len;
4329         const char *fn;
4330         char fname[13+1];
4331
4332         if(parent_tree){
4333                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
4334                         "Directory Information");
4335                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
4336         }
4337
4338         /* resume key */
4339         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
4340             trunc, has_find_id);
4341         if (*trunc)
4342                 return offset;
4343
4344         /* File Attributes */
4345         CHECK_BYTE_COUNT_SUBR(1);
4346         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
4347         *bcp -= 1;
4348
4349         /* last write time */
4350         CHECK_BYTE_COUNT_SUBR(4);
4351         offset = dissect_smb_datetime(tvb, tree, offset,
4352                 hf_smb_last_write_time,
4353                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
4354                 TRUE);
4355         *bcp -= 4;
4356
4357         /* File Size */
4358         CHECK_BYTE_COUNT_SUBR(4);
4359         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4360         COUNT_BYTES_SUBR(4);
4361
4362         /* file name */
4363         fn_len = 13;
4364         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4365                 TRUE, TRUE, bcp);
4366         CHECK_STRING_SUBR(fn);
4367         /* ensure that it's null-terminated */
4368         strncpy(fname, fn, 13);
4369         fname[13] = '\0';
4370         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4371                 fname);
4372         COUNT_BYTES_SUBR(fn_len);
4373
4374         *trunc = FALSE;
4375         return offset;
4376 }
4377
4378
4379 static int
4380 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
4381     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4382     gboolean has_find_id)
4383 {
4384         smb_info_t *si = pinfo->private_data;
4385         int fn_len;
4386         const char *fn;
4387         guint16 rkl;
4388         guint8 wc;
4389         guint16 bc;
4390         gboolean trunc;
4391
4392         WORD_COUNT;
4393
4394         /* max count */
4395         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4396         offset += 2;
4397
4398         /* Search Attributes */
4399         offset = dissect_search_attributes(tvb, tree, offset);
4400
4401         BYTE_COUNT;
4402
4403         /* buffer format */
4404         CHECK_BYTE_COUNT(1);
4405         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4406         COUNT_BYTES(1);
4407
4408         /* file name */
4409         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4410                 TRUE, FALSE, &bc);
4411         if (fn == NULL)
4412                 goto endofcommand;
4413         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4414                 fn);
4415         COUNT_BYTES(fn_len);
4416
4417         if (check_col(pinfo->cinfo, COL_INFO)) {
4418                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", fn);
4419         }
4420
4421         /* buffer format */
4422         CHECK_BYTE_COUNT(1);
4423         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4424         COUNT_BYTES(1);
4425
4426         /* resume key length */
4427         CHECK_BYTE_COUNT(2);
4428         rkl = tvb_get_letohs(tvb, offset);
4429         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
4430         COUNT_BYTES(2);
4431
4432         /* resume key */
4433         if(rkl){
4434                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
4435                     &bc, &trunc, has_find_id);
4436                 if (trunc)
4437                         goto endofcommand;
4438         }
4439
4440         END_OF_SMB
4441
4442         return offset;
4443 }
4444
4445 static int
4446 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4447     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4448 {
4449         return dissect_search_find_request(tvb, pinfo, tree, offset,
4450             smb_tree, FALSE);
4451 }
4452
4453 static int
4454 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4455     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4456 {
4457         return dissect_search_find_request(tvb, pinfo, tree, offset,
4458             smb_tree, TRUE);
4459 }
4460
4461 static int
4462 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4463     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4464 {
4465         return dissect_search_find_request(tvb, pinfo, tree, offset,
4466             smb_tree, TRUE);
4467 }
4468
4469 static int
4470 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4471     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4472     gboolean has_find_id)
4473 {
4474         guint16 count=0;
4475         guint8 wc;
4476         guint16 bc;
4477         gboolean trunc;
4478
4479         WORD_COUNT;
4480
4481         /* count */
4482         count = tvb_get_letohs(tvb, offset);
4483         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
4484         offset += 2;
4485
4486         BYTE_COUNT;
4487
4488         /* buffer format */
4489         CHECK_BYTE_COUNT(1);
4490         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4491         COUNT_BYTES(1);
4492
4493         /* data len */
4494         CHECK_BYTE_COUNT(2);
4495         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4496         COUNT_BYTES(2);
4497
4498         while(count--){
4499                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
4500                     &bc, &trunc, has_find_id);
4501                 if (trunc)
4502                         goto endofcommand;
4503         }
4504
4505         END_OF_SMB
4506
4507         return offset;
4508 }
4509
4510 static int
4511 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4512 {
4513         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4514             FALSE);
4515 }
4516
4517 static int
4518 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4519 {
4520         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4521             TRUE);
4522 }
4523
4524 static int
4525 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4526     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4527 {
4528         guint8 wc;
4529         guint16 bc;
4530         guint16 data_len;
4531
4532         WORD_COUNT;
4533
4534         /* reserved */
4535         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4536         offset += 2;
4537
4538         BYTE_COUNT;
4539
4540         /* buffer format */
4541         CHECK_BYTE_COUNT(1);
4542         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4543         COUNT_BYTES(1);
4544
4545         /* data len */
4546         CHECK_BYTE_COUNT(2);
4547         data_len = tvb_get_ntohs(tvb, offset);
4548         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
4549         COUNT_BYTES(2);
4550
4551         if (data_len != 0) {
4552                 CHECK_BYTE_COUNT(data_len);
4553                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
4554                     data_len, TRUE);
4555                 COUNT_BYTES(data_len);
4556         }
4557
4558         END_OF_SMB
4559
4560         return offset;
4561 }
4562
4563 static const value_string locking_ol_vals[] = {
4564         {0,     "Client is not holding oplock on this file"},
4565         {1,     "Level 2 oplock currently held by client"},
4566         {0, NULL}
4567 };
4568
4569 static const true_false_string tfs_lock_type_large = {
4570         "Large file locking format requested",
4571         "Large file locking format not requested"
4572 };
4573 static const true_false_string tfs_lock_type_cancel = {
4574         "Cancel outstanding lock request",
4575         "Don't cancel outstanding lock request"
4576 };
4577 static const true_false_string tfs_lock_type_change = {
4578         "Change lock type",
4579         "Don't change lock type"
4580 };
4581 static const true_false_string tfs_lock_type_oplock = {
4582         "This is an oplock break notification/response",
4583         "This is not an oplock break notification/response"
4584 };
4585 static const true_false_string tfs_lock_type_shared = {
4586         "This is a shared lock",
4587         "This is an exclusive lock"
4588 };
4589 static int
4590 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4591 {
4592         guint8  wc, cmd=0xff, lt=0;
4593         guint16 andxoffset=0, un=0, ln=0, bc, fid;
4594         guint32 to;
4595         proto_item *litem = NULL;
4596         proto_tree *ltree = NULL;
4597         proto_item *it = NULL;
4598         proto_tree *tr = NULL;
4599         int old_offset = offset;
4600
4601         WORD_COUNT;
4602
4603         /* next smb command */
4604         cmd = tvb_get_guint8(tvb, offset);
4605         if(cmd!=0xff){
4606                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4607         } else {
4608                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4609         }
4610         offset += 1;
4611
4612         /* reserved byte */
4613         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4614         offset += 1;
4615
4616         /* andxoffset */
4617         andxoffset = tvb_get_letohs(tvb, offset);
4618         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4619         offset += 2;
4620
4621         /* fid */
4622         fid = tvb_get_letohs(tvb, offset);
4623         add_fid(tvb, pinfo, tree, offset, 2, fid);
4624         offset += 2;
4625
4626         /* lock type */
4627         lt = tvb_get_guint8(tvb, offset);
4628         if(tree){
4629                 litem = proto_tree_add_text(tree, tvb, offset, 1,
4630                         "Lock Type: 0x%02x", lt);
4631                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
4632         }
4633         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
4634                 tvb, offset, 1, lt);
4635         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
4636                 tvb, offset, 1, lt);
4637         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
4638                 tvb, offset, 1, lt);
4639         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
4640                 tvb, offset, 1, lt);
4641         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
4642                 tvb, offset, 1, lt);
4643         offset += 1;
4644
4645         /* oplock level */
4646         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
4647         offset += 1;
4648
4649         /* timeout */
4650         to = tvb_get_letohl(tvb, offset);
4651         if (to == 0)
4652                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
4653         else if (to == 0xffffffff)
4654                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
4655         else
4656                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4657         offset += 4;
4658
4659         /* number of unlocks */
4660         un = tvb_get_letohs(tvb, offset);
4661         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
4662         offset += 2;
4663
4664         /* number of locks */
4665         ln = tvb_get_letohs(tvb, offset);
4666         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
4667         offset += 2;
4668
4669         BYTE_COUNT;
4670
4671         /* unlocks */
4672         if(un){
4673                 old_offset = offset;
4674
4675                 it = proto_tree_add_text(tree, tvb, offset, -1,
4676                         "Unlocks");
4677                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
4678                 while(un--){
4679                         proto_item *litem = NULL;
4680                         proto_tree *ltree = NULL;
4681                         if(lt&0x10){
4682                                 /* large lock format */
4683                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4684                                         "Unlock");
4685                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4686
4687                                 /* PID */
4688                                 CHECK_BYTE_COUNT(2);
4689                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4690                                 COUNT_BYTES(2);
4691
4692                                 /* 2 reserved bytes */
4693                                 CHECK_BYTE_COUNT(2);
4694                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4695                                 COUNT_BYTES(2);
4696
4697                                 /* offset */
4698                                 CHECK_BYTE_COUNT(8);
4699                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4700                                 COUNT_BYTES(8);
4701
4702                                 /* length */
4703                                 CHECK_BYTE_COUNT(8);
4704                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4705                                 COUNT_BYTES(8);
4706                         } else {
4707                                 /* normal lock format */
4708                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4709                                         "Unlock");
4710                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4711
4712                                 /* PID */
4713                                 CHECK_BYTE_COUNT(2);
4714                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4715                                 COUNT_BYTES(2);
4716
4717                                 /* offset */
4718                                 CHECK_BYTE_COUNT(4);
4719                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4720                                 COUNT_BYTES(4);
4721
4722                                 /* lock count */
4723                                 CHECK_BYTE_COUNT(4);
4724                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4725                                 COUNT_BYTES(4);
4726                         }
4727                 }
4728                 proto_item_set_len(it, offset-old_offset);
4729                 it = NULL;
4730         }
4731
4732         /* locks */
4733         if(ln){
4734                 old_offset = offset;
4735
4736                 it = proto_tree_add_text(tree, tvb, offset, -1,
4737                         "Locks");
4738                 tr = proto_item_add_subtree(it, ett_smb_locks);
4739                 while(ln--){
4740                         proto_item *litem = NULL;
4741                         proto_tree *ltree = NULL;
4742                         if(lt&0x10){
4743                                 /* large lock format */
4744                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4745                                         "Lock");
4746                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
4747
4748                                 /* PID */
4749                                 CHECK_BYTE_COUNT(2);
4750                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4751                                 COUNT_BYTES(2);
4752
4753                                 /* 2 reserved bytes */
4754                                 CHECK_BYTE_COUNT(2);
4755                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4756                                 COUNT_BYTES(2);
4757
4758                                 /* offset */
4759                                 CHECK_BYTE_COUNT(8);
4760                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4761                                 COUNT_BYTES(8);
4762
4763                                 /* length */
4764                                 CHECK_BYTE_COUNT(8);
4765                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4766                                 COUNT_BYTES(8);
4767                         } else {
4768                                 /* normal lock format */
4769                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4770                                         "Unlock");
4771                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4772
4773                                 /* PID */
4774                                 CHECK_BYTE_COUNT(2);
4775                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4776                                 COUNT_BYTES(2);
4777
4778                                 /* offset */
4779                                 CHECK_BYTE_COUNT(4);
4780                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4781                                 COUNT_BYTES(4);
4782
4783                                 /* lock count */
4784                                 CHECK_BYTE_COUNT(4);
4785                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4786                                 COUNT_BYTES(4);
4787                         }
4788                 }
4789                 proto_item_set_len(it, offset-old_offset);
4790                 it = NULL;
4791         }
4792
4793         END_OF_SMB
4794
4795         if (it != NULL) {
4796                 /*
4797                  * We ran out of byte count in the middle of dissecting
4798                  * the locks or the unlocks; set the site of the item
4799                  * we were dissecting.
4800                  */
4801                 proto_item_set_len(it, offset-old_offset);
4802         }
4803
4804         /* call AndXCommand (if there are any) */
4805         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4806
4807         return offset;
4808 }
4809
4810 static int
4811 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4812 {
4813         guint8  wc, cmd=0xff;
4814         guint16 andxoffset=0;
4815         guint16 bc;
4816
4817         WORD_COUNT;
4818
4819         /* next smb command */
4820         cmd = tvb_get_guint8(tvb, offset);
4821         if(cmd!=0xff){
4822                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4823         } else {
4824                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4825         }
4826         offset += 1;
4827
4828         /* reserved byte */
4829         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4830         offset += 1;
4831
4832         /* andxoffset */
4833         andxoffset = tvb_get_letohs(tvb, offset);
4834         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4835         offset += 2;
4836
4837         BYTE_COUNT;
4838
4839         END_OF_SMB
4840
4841         /* call AndXCommand (if there are any) */
4842         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4843
4844         return offset;
4845 }
4846
4847
4848 static const value_string oa_open_vals[] = {
4849         { 0,            "No action taken?"},
4850         { 1,            "The file existed and was opened"},
4851         { 2,            "The file did not exist but was created"},
4852         { 3,            "The file existed and was truncated"},
4853         {0,     NULL}
4854 };
4855 static const true_false_string tfs_oa_lock = {
4856         "File is currently opened only by this user",
4857         "File is opened by another user (or mode not supported by server)"
4858 };
4859 static int
4860 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
4861 {
4862         guint16 mask;
4863         proto_item *item = NULL;
4864         proto_tree *tree = NULL;
4865
4866         mask = tvb_get_letohs(tvb, offset);
4867
4868         if(parent_tree){
4869                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4870                         "Action: 0x%04x", mask);
4871                 tree = proto_item_add_subtree(item, ett_smb_open_action);
4872         }
4873
4874         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
4875                 tvb, offset, 2, mask);
4876         proto_tree_add_uint(tree, hf_smb_open_action_open,
4877                 tvb, offset, 2, mask);
4878
4879         offset += 2;
4880
4881         return offset;
4882 }
4883
4884 static const true_false_string tfs_open_flags_add_info = {
4885         "Additional information requested",
4886         "Additional information not requested"
4887 };
4888 static const true_false_string tfs_open_flags_ex_oplock = {
4889         "Exclusive oplock requested",
4890         "Exclusive oplock not requested"
4891 };
4892 static const true_false_string tfs_open_flags_batch_oplock = {
4893         "Batch oplock requested",
4894         "Batch oplock not requested"
4895 };
4896 static const true_false_string tfs_open_flags_ealen = {
4897         "Total length of EAs requested",
4898         "Total length of EAs not requested"
4899 };
4900 static int
4901 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4902 {
4903         guint16 mask;
4904         proto_item *item = NULL;
4905         proto_tree *tree = NULL;
4906
4907         mask = tvb_get_letohs(tvb, offset);
4908
4909         if(parent_tree){
4910                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4911                         "Flags: 0x%04x", mask);
4912                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
4913         }
4914
4915         if(bm&0x0001){
4916                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
4917                         tvb, offset, 2, mask);
4918         }
4919         if(bm&0x0002){
4920                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
4921                         tvb, offset, 2, mask);
4922         }
4923         if(bm&0x0004){
4924                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
4925                         tvb, offset, 2, mask);
4926         }
4927         if(bm&0x0008){
4928                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
4929                         tvb, offset, 2, mask);
4930         }
4931
4932         offset += 2;
4933
4934         return offset;
4935 }
4936
4937 static const value_string filetype_vals[] = {
4938         { 0,            "Disk file or directory"},
4939         { 1,            "Named pipe in byte mode"},
4940         { 2,            "Named pipe in message mode"},
4941         { 3,            "Spooled printer"},
4942         {0, NULL}
4943 };
4944 static int
4945 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4946 {
4947         guint8  wc, cmd=0xff;
4948         guint16 andxoffset=0, bc;
4949         smb_info_t *si = pinfo->private_data;
4950         int fn_len;
4951         const char *fn;
4952
4953         WORD_COUNT;
4954
4955         /* next smb command */
4956         cmd = tvb_get_guint8(tvb, offset);
4957         if(cmd!=0xff){
4958                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4959         } else {
4960                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4961         }
4962         offset += 1;
4963
4964         /* reserved byte */
4965         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4966         offset += 1;
4967
4968         /* andxoffset */
4969         andxoffset = tvb_get_letohs(tvb, offset);
4970         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4971         offset += 2;
4972
4973         /* open flags */
4974         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
4975
4976         /* desired access */
4977         offset = dissect_access(tvb, tree, offset, "Desired");
4978
4979         /* Search Attributes */
4980         offset = dissect_search_attributes(tvb, tree, offset);
4981
4982         /* File Attributes */
4983         offset = dissect_file_attributes(tvb, tree, offset);
4984
4985         /* creation time */
4986         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
4987
4988         /* open function */
4989         offset = dissect_open_function(tvb, tree, offset);
4990
4991         /* allocation size */
4992         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
4993         offset += 4;
4994
4995         /* 8 reserved bytes */
4996         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4997         offset += 8;
4998
4999         BYTE_COUNT;
5000
5001         /* file name */
5002         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5003                 FALSE, FALSE, &bc);
5004         if (fn == NULL)
5005                 goto endofcommand;
5006         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5007                 fn);
5008         COUNT_BYTES(fn_len);
5009
5010         if (check_col(pinfo->cinfo, COL_INFO)) {
5011                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
5012         }
5013
5014         END_OF_SMB
5015
5016         /* call AndXCommand (if there are any) */
5017         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5018
5019         return offset;
5020 }
5021
5022 static const true_false_string tfs_ipc_state_nonblocking = {
5023         "Reads/writes return immediately if no data available",
5024         "Reads/writes block if no data available"
5025 };
5026 static const value_string ipc_state_endpoint_vals[] = {
5027         { 0,            "Consumer end of pipe"},
5028         { 1,            "Server end of pipe"},
5029         {0,     NULL}
5030 };
5031 static const value_string ipc_state_pipe_type_vals[] = {
5032         { 0,            "Byte stream pipe"},
5033         { 1,            "Message pipe"},
5034         {0,     NULL}
5035 };
5036 static const value_string ipc_state_read_mode_vals[] = {
5037         { 0,            "Read pipe as a byte stream"},
5038         { 1,            "Read messages from pipe"},
5039         {0,     NULL}
5040 };
5041
5042 int
5043 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
5044     gboolean setstate)
5045 {
5046         guint16 mask;
5047         proto_item *item = NULL;
5048         proto_tree *tree = NULL;
5049
5050         mask = tvb_get_letohs(tvb, offset);
5051
5052         if(parent_tree){
5053                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5054                         "IPC State: 0x%04x", mask);
5055                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
5056         }
5057
5058         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
5059                 tvb, offset, 2, mask);
5060         if (!setstate) {
5061                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
5062                         tvb, offset, 2, mask);
5063                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
5064                         tvb, offset, 2, mask);
5065         }
5066         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
5067                 tvb, offset, 2, mask);
5068         if (!setstate) {
5069                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
5070                         tvb, offset, 2, mask);
5071         }
5072
5073         offset += 2;
5074
5075         return offset;
5076 }
5077
5078 static int
5079 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5080 {
5081         guint8  wc, cmd=0xff;
5082         guint16 andxoffset=0, bc;
5083         guint16 fid;
5084
5085         WORD_COUNT;
5086
5087         /* next smb command */
5088         cmd = tvb_get_guint8(tvb, offset);
5089         if(cmd!=0xff){
5090                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5091         } else {
5092                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5093         }
5094         offset += 1;
5095
5096         /* reserved byte */
5097         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5098         offset += 1;
5099
5100         /* andxoffset */
5101         andxoffset = tvb_get_letohs(tvb, offset);
5102         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5103         offset += 2;
5104
5105         /* fid */
5106         fid = tvb_get_letohs(tvb, offset);
5107         add_fid(tvb, pinfo, tree, offset, 2, fid);
5108         offset += 2;
5109
5110         /* File Attributes */
5111         offset = dissect_file_attributes(tvb, tree, offset);
5112
5113         /* last write time */
5114         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
5115
5116         /* File Size */
5117         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5118         offset += 4;
5119
5120         /* granted access */
5121         offset = dissect_access(tvb, tree, offset, "Granted");
5122
5123         /* File Type */
5124         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
5125         offset += 2;
5126
5127         /* IPC State */
5128         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
5129
5130         /* open_action */
5131         offset = dissect_open_action(tvb, tree, offset);
5132
5133         /* server fid */
5134         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
5135         offset += 4;
5136
5137         /* 2 reserved bytes */
5138         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5139         offset += 2;
5140
5141         BYTE_COUNT;
5142
5143         END_OF_SMB
5144
5145         /* call AndXCommand (if there are any) */
5146         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5147
5148         return offset;
5149 }
5150
5151 static int
5152 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5153 {
5154         guint8  wc, cmd=0xff;
5155         guint16 andxoffset=0, bc, maxcnt = 0;
5156         guint32 ofs = 0;
5157         smb_info_t *si;
5158         unsigned int fid;
5159
5160         WORD_COUNT;
5161
5162         /* next smb command */
5163         cmd = tvb_get_guint8(tvb, offset);
5164         if(cmd!=0xff){
5165                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5166         } else {
5167                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5168         }
5169         offset += 1;
5170
5171         /* reserved byte */
5172         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5173         offset += 1;
5174
5175         /* andxoffset */
5176         andxoffset = tvb_get_letohs(tvb, offset);
5177         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5178         offset += 2;
5179
5180         /* fid */
5181         fid = tvb_get_letohs(tvb, offset);
5182         add_fid(tvb, pinfo, tree, offset, 2, fid);
5183         offset += 2;
5184         if (!pinfo->fd->flags.visited) {
5185                 /* remember the FID for the processing of the response */
5186                 si = (smb_info_t *)pinfo->private_data;
5187                 si->sip->extra_info=(void *)fid;
5188         }
5189
5190         /* offset */
5191         ofs = tvb_get_letohl(tvb, offset);
5192         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5193         offset += 4;
5194
5195         /* max count */
5196         maxcnt = tvb_get_letohs(tvb, offset);
5197         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
5198         offset += 2;
5199
5200         if (check_col(pinfo->cinfo, COL_INFO))
5201                 col_append_fstr(pinfo->cinfo, COL_INFO,
5202                                 ", %u byte%s at offset %u", maxcnt,
5203                                 (maxcnt == 1) ? "" : "s", ofs);
5204
5205         /* min count */
5206         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
5207         offset += 2;
5208
5209         /* XXX - max count high */
5210         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5211         offset += 4;
5212
5213         /* remaining */
5214         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5215         offset += 2;
5216
5217         if(wc==12){
5218                 /* high offset */
5219                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5220                 offset += 4;
5221         }
5222
5223         BYTE_COUNT;
5224
5225         END_OF_SMB
5226
5227         /* call AndXCommand (if there are any) */
5228         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5229
5230         return offset;
5231 }
5232
5233 static int
5234 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5235 {
5236         guint8  wc, cmd=0xff;
5237         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
5238         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5239         int fid=0;
5240
5241         WORD_COUNT;
5242
5243         /* next smb command */
5244         cmd = tvb_get_guint8(tvb, offset);
5245         if(cmd!=0xff){
5246                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5247         } else {
5248                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5249         }
5250         offset += 1;
5251
5252         /* reserved byte */
5253         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5254         offset += 1;
5255
5256         /* andxoffset */
5257         andxoffset = tvb_get_letohs(tvb, offset);
5258         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5259         offset += 2;
5260
5261         /* If we have seen the request, then print which FID this refers to */
5262         /* first check if we have seen the request */
5263         if(si->sip != NULL && si->sip->frame_req>0){
5264                 fid=(int)si->sip->extra_info;
5265                 add_fid(tvb, pinfo, tree, 0, 0, fid);
5266         }
5267
5268         /* remaining */
5269         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5270         offset += 2;
5271
5272         /* data compaction mode */
5273         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
5274         offset += 2;
5275
5276         /* 2 reserved bytes */
5277         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5278         offset += 2;
5279
5280         /* data len */
5281         datalen = tvb_get_letohs(tvb, offset);
5282         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5283         offset += 2;
5284
5285         if (check_col(pinfo->cinfo, COL_INFO))
5286                 col_append_fstr(pinfo->cinfo, COL_INFO,
5287                                 ", %u byte%s", datalen,
5288                                 (datalen == 1) ? "" : "s");
5289
5290         /* data offset */
5291         dataoffset=tvb_get_letohs(tvb, offset);
5292         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5293         offset += 2;
5294
5295         /* 10 reserved bytes */
5296         /* XXX - first 2 bytes are data length high, not reserved */
5297         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
5298         offset += 10;
5299
5300         BYTE_COUNT;
5301
5302         /* is this part of DCERPC over SMB reassembly?*/
5303         if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited
5304             && (bc<=tvb_length_remaining(tvb, offset)) ){
5305                 gpointer hash_value;
5306                 if (si->sip != NULL && (hash_value = g_hash_table_lookup(
5307                                                 si->ct->dcerpc_fid_to_frame,
5308                                                 si->sip->extra_info)) != NULL) {
5309                         fragment_data *fd_head;
5310                         guint32 frame = GPOINTER_TO_UINT(hash_value);
5311
5312                         /* first fragment is always from a SMB Trans command and
5313                            offset 0 of the following read/write SMB commands start
5314                            BEYOND the first Trans SMB payload. Look for offset
5315                            in first read fragment */
5316                         fd_head=fragment_get(pinfo, frame, dcerpc_fragment_table);
5317                         if(fd_head){
5318                                 /* skip to last fragment  and add this data there*/
5319                                 while(fd_head->next){
5320                                         fd_head=fd_head->next;
5321                                 }
5322                                 /* if dataoffset was not specified in the SMB command
5323                                    then we try to guess it as good as we can
5324                                 */
5325                                 if(dataoffset==0){
5326                                         dataoffset=offset+bc-datalen;
5327                                 }
5328                                 fd_head=fragment_add(tvb, dataoffset, pinfo,
5329                                         frame, dcerpc_fragment_table,
5330                                         fd_head->offset+fd_head->len,
5331                                         datalen, TRUE);
5332                                 /* we completed reassembly, abort searching for more
5333                                    fragments*/
5334                                 if(fd_head){
5335                                         g_hash_table_remove(si->ct->dcerpc_fid_to_frame,
5336                                                 si->sip->extra_info);
5337                                 }
5338                         }
5339                 }
5340         }
5341
5342         /* another way to transport DCERPC over SMB is to skip Transaction completely and just
5343            read write */
5344         if(bc){
5345                 if(si->sip != NULL && si->sip->flags&SMB_SIF_TID_IS_IPC){
5346                         /* dcerpc call */
5347                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
5348                             top_tree, offset, bc, datalen, fid);
5349                 } else {
5350                         /* ordinary file data, or we didn't see the request,
5351                            so we don't know whether this is a DCERPC call
5352                            or not */
5353                         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
5354                 }
5355                 bc = 0;
5356         }
5357
5358         END_OF_SMB
5359
5360         /* call AndXCommand (if there are any) */
5361         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5362
5363         return offset;
5364 }
5365
5366 static int
5367 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5368 {
5369         guint32 ofs=0;
5370         guint8  wc, cmd=0xff;
5371         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
5372         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5373         unsigned int fid=0;
5374
5375         WORD_COUNT;
5376
5377         /* next smb command */
5378         cmd = tvb_get_guint8(tvb, offset);
5379         if(cmd!=0xff){
5380                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5381         } else {
5382                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5383         }
5384         offset += 1;
5385
5386         /* reserved byte */
5387         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5388         offset += 1;
5389
5390         /* andxoffset */
5391         andxoffset = tvb_get_letohs(tvb, offset);
5392         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5393         offset += 2;
5394
5395         /* fid */
5396         fid = tvb_get_letohs(tvb, offset);
5397         add_fid(tvb, pinfo, tree, offset, 2, fid);
5398         offset += 2;
5399         if (!pinfo->fd->flags.visited) {
5400                 /* remember the FID for the processing of the response */
5401                 si->sip->extra_info=(void *)fid;
5402         }
5403
5404         /* offset */
5405         ofs = tvb_get_letohl(tvb, offset);
5406         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5407         offset += 4;
5408
5409         /* reserved */
5410         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5411         offset += 4;
5412
5413         /* mode */
5414         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
5415
5416         /* remaining */
5417         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5418         offset += 2;
5419
5420         /* XXX - data length high */
5421         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5422         offset += 2;
5423
5424         /* data len */
5425         datalen = tvb_get_letohs(tvb, offset);
5426         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5427         offset += 2;
5428
5429         /* data offset */
5430         dataoffset=tvb_get_letohs(tvb, offset);
5431         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5432         offset += 2;
5433
5434         /* FIXME: add byte/offset to COL_INFO */
5435
5436         if(wc==14){
5437                 /* high offset */
5438                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5439                 offset += 4;
5440         }
5441
5442         BYTE_COUNT;
5443
5444         /* is this part of DCERPC over SMB reassembly?*/
5445         if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited && (bc<=tvb_length_remaining(tvb, offset)) ){
5446                 gpointer hash_value;
5447                 hash_value = g_hash_table_lookup(si->ct->dcerpc_fid_to_frame,
5448                         si->sip->extra_info);
5449                 if(hash_value){
5450                         fragment_data *fd_head;
5451                         guint32 frame = GPOINTER_TO_UINT(hash_value);
5452
5453                         /* first fragment is always from a SMB Trans command and
5454                            offset 0 of the following read/write SMB commands start
5455                            BEYOND the first Trans SMB payload. Look for offset
5456                            in first read fragment */
5457                         fd_head=fragment_get(pinfo, frame, dcerpc_fragment_table);
5458                         if(fd_head){
5459                                 /* skip to last fragment  and add this data there*/
5460                                 while(fd_head->next){
5461                                         fd_head=fd_head->next;
5462                                 }
5463                                 /* if dataoffset was not specified in the SMB command
5464                                    then we try to guess it as good as we can
5465                                 */
5466                                 if(dataoffset==0){
5467                                         dataoffset=offset+bc-datalen;
5468                                 }
5469                                 fd_head=fragment_add(tvb, dataoffset, pinfo,
5470                                         frame, dcerpc_fragment_table,
5471                                         fd_head->offset+fd_head->len,
5472                                         datalen, TRUE);
5473                                 /* we completed reassembly, abort searching for more
5474                                    fragments*/
5475                                 if(fd_head){
5476                                         g_hash_table_remove(si->ct->dcerpc_fid_to_frame,
5477                                                 si->sip->extra_info);
5478                                 }
5479                         }
5480                 }
5481         }
5482
5483         /* file data */
5484         if (bc != 0) {
5485                 if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
5486                         /* dcerpc call */
5487                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
5488                             top_tree, offset, bc, datalen, fid);
5489                 } else {
5490                         /* ordinary file data */
5491                         offset = dissect_file_data(tvb, tree, offset,
5492                             bc, datalen);
5493                 }
5494                 bc = 0;
5495         }
5496
5497         END_OF_SMB
5498
5499         /* call AndXCommand (if there are any) */
5500         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5501
5502         return offset;
5503 }
5504
5505 static int
5506 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5507 {
5508         guint8  wc, cmd=0xff;
5509         guint16 andxoffset=0, bc;
5510         smb_info_t *si;
5511
5512         WORD_COUNT;
5513
5514         /* next smb command */
5515         cmd = tvb_get_guint8(tvb, offset);
5516         if(cmd!=0xff){
5517                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5518         } else {
5519                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5520         }
5521         offset += 1;
5522
5523         /* reserved byte */
5524         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5525         offset += 1;
5526
5527         /* andxoffset */
5528         andxoffset = tvb_get_letohs(tvb, offset);
5529         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5530         offset += 2;
5531
5532         /* If we have seen the request, then print which FID this refers to */
5533         si = (smb_info_t *)pinfo->private_data;
5534         /* first check if we have seen the request */
5535         if(si->sip != NULL && si->sip->frame_req>0){
5536                 add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
5537         }
5538
5539         /* write count */
5540         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
5541         offset += 2;
5542
5543         /* remaining */
5544         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5545         offset += 2;
5546
5547         /* 4 reserved bytes */
5548         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5549         offset += 4;
5550
5551         BYTE_COUNT;
5552
5553         END_OF_SMB
5554
5555         /* call AndXCommand (if there are any) */
5556         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5557
5558         return offset;
5559 }
5560
5561
5562 static const true_false_string tfs_setup_action_guest = {
5563         "Logged in as GUEST",
5564         "Not logged in as GUEST"
5565 };
5566 static int
5567 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5568 {
5569         guint16 mask;
5570         proto_item *item = NULL;
5571         proto_tree *tree = NULL;
5572
5573         mask = tvb_get_letohs(tvb, offset);
5574
5575         if(parent_tree){
5576                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5577                         "Action: 0x%04x", mask);
5578                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
5579         }
5580
5581         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
5582                 tvb, offset, 2, mask);
5583
5584         offset += 2;
5585
5586         return offset;
5587 }
5588
5589
5590 static int
5591 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5592 {
5593         guint8  wc, cmd=0xff;
5594         guint16 bc;
5595         guint16 andxoffset=0;
5596         smb_info_t *si = pinfo->private_data;
5597         int an_len;
5598         const char *an;
5599         int dn_len;
5600         const char *dn;
5601         guint16 pwlen=0;
5602         guint16 sbloblen=0;
5603         guint16 apwlen=0, upwlen=0;
5604
5605         WORD_COUNT;
5606
5607         /* next smb command */
5608         cmd = tvb_get_guint8(tvb, offset);
5609         if(cmd!=0xff){
5610                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5611         } else {
5612                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5613         }
5614         offset += 1;
5615
5616         /* reserved byte */
5617         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5618         offset += 1;
5619
5620         /* andxoffset */
5621         andxoffset = tvb_get_letohs(tvb, offset);
5622         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5623         offset += 2;
5624
5625         /* Maximum Buffer Size */
5626         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
5627         offset += 2;
5628
5629         /* Maximum Multiplex Count */
5630         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
5631         offset += 2;
5632
5633         /* VC Number */
5634         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
5635         offset += 2;
5636
5637         /* session key */
5638         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
5639         offset += 4;
5640
5641         switch (wc) {
5642         case 10:
5643                 /* password length, ASCII*/
5644                 pwlen = tvb_get_letohs(tvb, offset);
5645                 proto_tree_add_uint(tree, hf_smb_password_len,
5646                         tvb, offset, 2, pwlen);
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                 break;
5654
5655         case 12:
5656                 /* security blob length */
5657                 sbloblen = tvb_get_letohs(tvb, offset);
5658                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5659                 offset += 2;
5660
5661                 /* 4 reserved bytes */
5662                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5663                 offset += 4;
5664
5665                 /* capabilities */
5666                 dissect_negprot_capabilities(tvb, tree, offset);
5667                 offset += 4;
5668
5669                 break;
5670
5671         case 13:
5672                 /* password length, ANSI*/
5673                 apwlen = tvb_get_letohs(tvb, offset);
5674                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
5675                         tvb, offset, 2, apwlen);
5676                 offset += 2;
5677
5678                 /* password length, Unicode*/
5679                 upwlen = tvb_get_letohs(tvb, offset);
5680                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
5681                         tvb, offset, 2, upwlen);
5682                 offset += 2;
5683
5684                 /* 4 reserved bytes */
5685                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5686                 offset += 4;
5687
5688                 /* capabilities */
5689                 dissect_negprot_capabilities(tvb, tree, offset);
5690                 offset += 4;
5691
5692                 break;
5693         }
5694
5695         BYTE_COUNT;
5696
5697         if (wc==12) {
5698                 proto_item *blob_item;
5699
5700                 /* security blob */
5701
5702                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
5703                                                 tvb, offset, sbloblen, TRUE);
5704
5705                 if(sbloblen){
5706                         tvbuff_t *gssapi_tvb;
5707                         proto_tree *gssapi_tree;
5708
5709                         CHECK_BYTE_COUNT(sbloblen);
5710
5711                         gssapi_tree = proto_item_add_subtree(
5712                                 blob_item, ett_smb_gssapi);
5713
5714                         gssapi_tvb = tvb_new_subset(
5715                                 tvb, offset, sbloblen, sbloblen);
5716
5717                         call_dissector(
5718                                 gssapi_handle, gssapi_tvb, pinfo, gssapi_tree);
5719
5720                         COUNT_BYTES(sbloblen);
5721                 }
5722
5723                 /* OS */
5724                 an = get_unicode_or_ascii_string(tvb, &offset,
5725                         si->unicode, &an_len, FALSE, FALSE, &bc);
5726                 if (an == NULL)
5727                         goto endofcommand;
5728                 proto_tree_add_string(tree, hf_smb_os, tvb,
5729                         offset, an_len, an);
5730                 COUNT_BYTES(an_len);
5731
5732                 /* LANMAN */
5733                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5734                  * padding/null string/whatever in front of this. W2K doesn't
5735                  * appear to. I suspect that's a bug that got fixed; I also
5736                  * suspect that, in practice, nobody ever looks at that field
5737                  * because the bug didn't appear to get fixed until NT 5.0....
5738                  */
5739                 an = get_unicode_or_ascii_string(tvb, &offset,
5740                         si->unicode, &an_len, FALSE, FALSE, &bc);
5741                 if (an == NULL)
5742                         goto endofcommand;
5743                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5744                         offset, an_len, an);
5745                 COUNT_BYTES(an_len);
5746
5747                 /* Primary domain */
5748                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5749                  * byte in front of this, at least if all the strings are
5750                  * ASCII and the account name is empty. Another bug?
5751                  */
5752                 dn = get_unicode_or_ascii_string(tvb, &offset,
5753                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5754                 if (dn == NULL)
5755                         goto endofcommand;
5756                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5757                         offset, dn_len, dn);
5758                 COUNT_BYTES(dn_len);
5759         } else {
5760                 switch (wc) {
5761
5762                 case 10:
5763                         if(pwlen){
5764                                 /* password, ASCII */
5765                                 CHECK_BYTE_COUNT(pwlen);
5766                                 proto_tree_add_item(tree, hf_smb_password,
5767                                         tvb, offset, pwlen, TRUE);
5768                                 COUNT_BYTES(pwlen);
5769                         }
5770
5771                         break;
5772
5773                 case 13:
5774                         if(apwlen){
5775                                 /* password, ANSI */
5776                                 CHECK_BYTE_COUNT(apwlen);
5777                                 proto_tree_add_item(tree, hf_smb_ansi_password,
5778                                         tvb, offset, apwlen, TRUE);
5779                                 COUNT_BYTES(apwlen);
5780                         }
5781
5782                         if(upwlen){
5783                                 /* password, Unicode */
5784                                 CHECK_BYTE_COUNT(upwlen);
5785                                 proto_tree_add_item(tree, hf_smb_unicode_password,
5786                                         tvb, offset, upwlen, TRUE);
5787                                 COUNT_BYTES(upwlen);
5788                         }
5789
5790                         break;
5791                 }
5792
5793                 /* Account Name */
5794                 an = get_unicode_or_ascii_string(tvb, &offset,
5795                         si->unicode, &an_len, FALSE, FALSE, &bc);
5796                 if (an == NULL)
5797                         goto endofcommand;
5798                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
5799                         an);
5800                 COUNT_BYTES(an_len);
5801
5802                 /* Primary domain */
5803                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5804                  * byte in front of this, at least if all the strings are
5805                  * ASCII and the account name is empty. Another bug?
5806                  */
5807                 dn = get_unicode_or_ascii_string(tvb, &offset,
5808                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5809                 if (dn == NULL)
5810                         goto endofcommand;
5811                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5812                         offset, dn_len, dn);
5813                 COUNT_BYTES(dn_len);
5814
5815                 if (check_col(pinfo->cinfo, COL_INFO)) {
5816                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
5817
5818                         if (!dn[0] && !an[0])
5819                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5820                                                 "anonymous");
5821                         else
5822                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5823                                                 "%s\\%s", dn,an);
5824                 }
5825
5826                 /* OS */
5827                 an = get_unicode_or_ascii_string(tvb, &offset,
5828                         si->unicode, &an_len, FALSE, FALSE, &bc);
5829                 if (an == NULL)
5830                         goto endofcommand;
5831                 proto_tree_add_string(tree, hf_smb_os, tvb,
5832                         offset, an_len, an);
5833                 COUNT_BYTES(an_len);
5834
5835                 /* LANMAN */
5836                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5837                  * padding/null string/whatever in front of this. W2K doesn't
5838                  * appear to. I suspect that's a bug that got fixed; I also
5839                  * suspect that, in practice, nobody ever looks at that field
5840                  * because the bug didn't appear to get fixed until NT 5.0....
5841                  */
5842                 an = get_unicode_or_ascii_string(tvb, &offset,
5843                         si->unicode, &an_len, FALSE, FALSE, &bc);
5844                 if (an == NULL)
5845                         goto endofcommand;
5846                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5847                         offset, an_len, an);
5848                 COUNT_BYTES(an_len);
5849         }
5850
5851         END_OF_SMB
5852
5853         /* call AndXCommand (if there are any) */
5854         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5855
5856         return offset;
5857 }
5858
5859 static int
5860 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5861 {
5862         guint8  wc, cmd=0xff;
5863         guint16 andxoffset=0, bc;
5864         guint16 sbloblen=0;
5865         smb_info_t *si = pinfo->private_data;
5866         int an_len;
5867         const char *an;
5868
5869         WORD_COUNT;
5870
5871         /* next smb command */
5872         cmd = tvb_get_guint8(tvb, offset);
5873         if(cmd!=0xff){
5874                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5875         } else {
5876                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5877         }
5878         offset += 1;
5879
5880         /* reserved byte */
5881         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5882         offset += 1;
5883
5884         /* andxoffset */
5885         andxoffset = tvb_get_letohs(tvb, offset);
5886         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5887         offset += 2;
5888
5889         /* flags */
5890         offset = dissect_setup_action(tvb, tree, offset);
5891
5892         if(wc==4){
5893                 /* security blob length */
5894                 sbloblen = tvb_get_letohs(tvb, offset);
5895                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5896                 offset += 2;
5897         }
5898
5899         BYTE_COUNT;
5900
5901         if(wc==4) {
5902                 proto_item *blob_item;
5903
5904                 /* security blob */
5905
5906                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
5907                                                 tvb, offset, sbloblen, TRUE);
5908
5909                 if(sbloblen){
5910                         tvbuff_t *gssapi_tvb;
5911                         proto_tree *gssapi_tree;
5912
5913                         CHECK_BYTE_COUNT(sbloblen);
5914
5915                         gssapi_tree = proto_item_add_subtree(
5916                                 blob_item, ett_smb_gssapi);
5917
5918                         gssapi_tvb = tvb_new_subset(
5919                                 tvb, offset, sbloblen, sbloblen);
5920
5921                         call_dissector(
5922                                 gssapi_handle, gssapi_tvb, pinfo, gssapi_tree);
5923
5924                         COUNT_BYTES(sbloblen);
5925                 }
5926         }
5927
5928         /* OS */
5929         an = get_unicode_or_ascii_string(tvb, &offset,
5930                 si->unicode, &an_len, FALSE, FALSE, &bc);
5931         if (an == NULL)
5932                 goto endofcommand;
5933         proto_tree_add_string(tree, hf_smb_os, tvb,
5934                 offset, an_len, an);
5935         COUNT_BYTES(an_len);
5936
5937         /* LANMAN */
5938         an = get_unicode_or_ascii_string(tvb, &offset,
5939                 si->unicode, &an_len, FALSE, FALSE, &bc);
5940         if (an == NULL)
5941                 goto endofcommand;
5942         proto_tree_add_string(tree, hf_smb_lanman, tvb,
5943                 offset, an_len, an);
5944         COUNT_BYTES(an_len);
5945
5946         if(wc==3) {
5947                 /* Primary domain */
5948                 an = get_unicode_or_ascii_string(tvb, &offset,
5949                         si->unicode, &an_len, FALSE, FALSE, &bc);
5950                 if (an == NULL)
5951                         goto endofcommand;
5952                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5953                         offset, an_len, an);
5954                 COUNT_BYTES(an_len);
5955         }
5956
5957         END_OF_SMB
5958
5959         /* call AndXCommand (if there are any) */
5960         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5961
5962         return offset;
5963 }
5964
5965
5966 static int
5967 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5968 {
5969         guint8  wc, cmd=0xff;
5970         guint16 andxoffset=0;
5971         guint16 bc;
5972
5973         WORD_COUNT;
5974
5975         /* next smb command */
5976         cmd = tvb_get_guint8(tvb, offset);
5977         if(cmd!=0xff){
5978                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5979         } else {
5980                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5981         }
5982         offset += 1;
5983
5984         /* reserved byte */
5985         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5986         offset += 1;
5987
5988         /* andxoffset */
5989         andxoffset = tvb_get_letohs(tvb, offset);
5990         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5991         offset += 2;
5992
5993         BYTE_COUNT;
5994
5995         END_OF_SMB
5996
5997         /* call AndXCommand (if there are any) */
5998         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5999
6000         return offset;
6001 }
6002
6003
6004 static const true_false_string tfs_connect_support_search = {
6005         "Exclusive search bits supported",
6006         "Exclusive search bits not supported"
6007 };
6008 static const true_false_string tfs_connect_support_in_dfs = {
6009         "Share is in Dfs",
6010         "Share isn't in Dfs"
6011 };
6012
6013 static int
6014 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6015 {
6016         guint16 mask;
6017         proto_item *item = NULL;
6018         proto_tree *tree = NULL;
6019
6020         mask = tvb_get_letohs(tvb, offset);
6021
6022         if(parent_tree){
6023                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6024                         "Optional Support: 0x%04x", mask);
6025                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
6026         }
6027
6028         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
6029                 tvb, offset, 2, mask);
6030         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
6031                 tvb, offset, 2, mask);
6032
6033         offset += 2;
6034
6035         return offset;
6036 }
6037
6038 static const true_false_string tfs_disconnect_tid = {
6039         "DISCONNECT TID",
6040         "Do NOT disconnect TID"
6041 };
6042
6043 static int
6044 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6045 {
6046         guint16 mask;
6047         proto_item *item = NULL;
6048         proto_tree *tree = NULL;
6049
6050         mask = tvb_get_letohs(tvb, offset);
6051
6052         if(parent_tree){
6053                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6054                         "Flags: 0x%04x", mask);
6055                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
6056         }
6057
6058         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
6059                 tvb, offset, 2, mask);
6060
6061         offset += 2;
6062
6063         return offset;
6064 }
6065
6066 static int
6067 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6068 {
6069         guint8  wc, cmd=0xff;
6070         guint16 bc;
6071         guint16 andxoffset=0, pwlen=0;
6072         smb_info_t *si = pinfo->private_data;
6073         int an_len;
6074         const char *an;
6075
6076         WORD_COUNT;
6077
6078         /* next smb command */
6079         cmd = tvb_get_guint8(tvb, offset);
6080         if(cmd!=0xff){
6081                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6082         } else {
6083                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
6084         }
6085         offset += 1;
6086
6087         /* reserved byte */
6088         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6089         offset += 1;
6090
6091         /* andxoffset */
6092         andxoffset = tvb_get_letohs(tvb, offset);
6093         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6094         offset += 2;
6095
6096         /* flags */
6097         offset = dissect_connect_flags(tvb, tree, offset);
6098
6099         /* password length*/
6100         pwlen = tvb_get_letohs(tvb, offset);
6101         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
6102         offset += 2;
6103
6104         BYTE_COUNT;
6105
6106         /* password */
6107         CHECK_BYTE_COUNT(pwlen);
6108         proto_tree_add_item(tree, hf_smb_password,
6109                 tvb, offset, pwlen, TRUE);
6110         COUNT_BYTES(pwlen);
6111
6112         /* Path */
6113         an = get_unicode_or_ascii_string(tvb, &offset,
6114                 si->unicode, &an_len, FALSE, FALSE, &bc);
6115         if (an == NULL)
6116                 goto endofcommand;
6117         proto_tree_add_string(tree, hf_smb_path, tvb,
6118                 offset, an_len, an);
6119         COUNT_BYTES(an_len);
6120
6121         if (check_col(pinfo->cinfo, COL_INFO)) {
6122                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
6123         }
6124
6125         /*
6126          * NOTE: the Service string is always ASCII, even if the
6127          * "strings are Unicode" bit is set in the flags2 field
6128          * of the SMB.
6129          */
6130
6131         /* Service */
6132         /* XXX - what if this runs past bc? */
6133         an_len = tvb_strsize(tvb, offset);
6134         CHECK_BYTE_COUNT(an_len);
6135         an = tvb_get_ptr(tvb, offset, an_len);
6136         proto_tree_add_string(tree, hf_smb_service, tvb,
6137                 offset, an_len, an);
6138         COUNT_BYTES(an_len);
6139
6140         END_OF_SMB
6141
6142         /* call AndXCommand (if there are any) */
6143         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6144
6145         return offset;
6146 }
6147
6148
6149 static int
6150 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6151 {
6152         guint8  wc, wleft, cmd=0xff;
6153         guint16 andxoffset=0;
6154         guint16 bc;
6155         int an_len;
6156         const char *an;
6157         smb_info_t *si = pinfo->private_data;
6158
6159         WORD_COUNT;
6160
6161         wleft = wc;     /* this is at least 1 */
6162
6163         /* next smb command */
6164         cmd = tvb_get_guint8(tvb, offset);
6165         if(cmd!=0xff){
6166                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6167         } else {
6168                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
6169         }
6170         offset += 1;
6171
6172         /* reserved byte */
6173         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6174         offset += 1;
6175
6176         wleft--;
6177         if (wleft == 0)
6178                 goto bytecount;
6179
6180         /* andxoffset */
6181         andxoffset = tvb_get_letohs(tvb, offset);
6182         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6183         offset += 2;
6184         wleft--;
6185         if (wleft == 0)
6186                 goto bytecount;
6187
6188         /* flags */
6189         offset = dissect_connect_support_bits(tvb, tree, offset);
6190         wleft--;
6191
6192         /* XXX - I've seen captures where this is 7, but I have no
6193            idea how to dissect it.  I'm guessing the third word
6194            contains connect support bits, which looks plausible
6195            from the values I've seen. */
6196
6197         while (wleft != 0) {
6198                 proto_tree_add_text(tree, tvb, offset, 2,
6199                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
6200                 offset += 2;
6201                 wleft--;
6202         }
6203
6204         BYTE_COUNT;
6205
6206         /*
6207          * NOTE: even though the SNIA CIFS spec doesn't say there's
6208          * a "Service" string if there's a word count of 2, the
6209          * document at
6210          *
6211          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
6212          *
6213          * (it's in an ugly format - text intended to be sent to a
6214          * printer, with backspaces and overstrikes used for boldfacing
6215          * and underlining; UNIX "col -b" can be used to strip the
6216          * overstrikes out) says there's a "Service" string there, and
6217          * some network traffic has it.
6218          */
6219
6220         /*
6221          * NOTE: the Service string is always ASCII, even if the
6222          * "strings are Unicode" bit is set in the flags2 field
6223          * of the SMB.
6224          */
6225
6226         /* Service */
6227         /* XXX - what if this runs past bc? */
6228         an_len = tvb_strsize(tvb, offset);
6229         CHECK_BYTE_COUNT(an_len);
6230         an = tvb_get_ptr(tvb, offset, an_len);
6231         proto_tree_add_string(tree, hf_smb_service, tvb,
6232                 offset, an_len, an);
6233         COUNT_BYTES(an_len);
6234
6235         /* Now when we know the service type, store it so that we know it for later commands down
6236            this tree */
6237         if(!pinfo->fd->flags.visited){
6238                 /* Remove any previous entry for this TID */
6239                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
6240                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
6241                 }
6242                 if(strcmp(an,"IPC") == 0){
6243                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
6244                 } else {
6245                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
6246                 }
6247         }
6248
6249
6250         if(wc==3){
6251                 if (bc != 0) {
6252                         /*
6253                          * Sometimes this isn't present.
6254                          */
6255
6256                         /* Native FS */
6257                         an = get_unicode_or_ascii_string(tvb, &offset,
6258                                 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
6259                                 &bc);
6260                         if (an == NULL)
6261                                 goto endofcommand;
6262                         proto_tree_add_string(tree, hf_smb_fs, tvb,
6263                                 offset, an_len, an);
6264                         COUNT_BYTES(an_len);
6265                 }
6266         }
6267
6268         END_OF_SMB
6269
6270         /* call AndXCommand (if there are any) */
6271         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6272
6273         return offset;
6274 }
6275
6276
6277
6278 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6279    NT Transaction command  begins here
6280    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
6281 #define NT_TRANS_CREATE         1
6282 #define NT_TRANS_IOCTL          2
6283 #define NT_TRANS_SSD            3
6284 #define NT_TRANS_NOTIFY         4
6285 #define NT_TRANS_RENAME         5
6286 #define NT_TRANS_QSD            6
6287 #define NT_TRANS_GET_USER_QUOTA 7
6288 #define NT_TRANS_SET_USER_QUOTA 8
6289 static const value_string nt_cmd_vals[] = {
6290         {NT_TRANS_CREATE,               "NT CREATE"},
6291         {NT_TRANS_IOCTL,                "NT IOCTL"},
6292         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
6293         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
6294         {NT_TRANS_RENAME,               "NT RENAME"},
6295         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
6296         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
6297         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
6298         {0, NULL}
6299 };
6300
6301 static const value_string nt_ioctl_isfsctl_vals[] = {
6302         {0,     "Device IOCTL"},
6303         {1,     "FS control : FSCTL"},
6304         {0, NULL}
6305 };
6306
6307 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
6308 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
6309         "Apply the command to share root handle (MUST BE Dfs)",
6310         "Apply to this share",
6311 };
6312
6313 static const value_string nt_notify_action_vals[] = {
6314         {1,     "ADDED (object was added"},
6315         {2,     "REMOVED (object was removed)"},
6316         {3,     "MODIFIED (object was modified)"},
6317         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
6318         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
6319         {6,     "ADDED_STREAM (a stream was added)"},
6320         {7,     "REMOVED_STREAM (a stream was removed)"},
6321         {8,     "MODIFIED_STREAM (a stream was modified)"},
6322         {0, NULL}
6323 };
6324
6325 static const value_string watch_tree_vals[] = {
6326         {0,     "Current directory only"},
6327         {1,     "Subdirectories also"},
6328         {0, NULL}
6329 };
6330
6331 #define NT_NOTIFY_STREAM_WRITE  0x00000800
6332 #define NT_NOTIFY_STREAM_SIZE   0x00000400
6333 #define NT_NOTIFY_STREAM_NAME   0x00000200
6334 #define NT_NOTIFY_SECURITY      0x00000100
6335 #define NT_NOTIFY_EA            0x00000080
6336 #define NT_NOTIFY_CREATION      0x00000040
6337 #define NT_NOTIFY_LAST_ACCESS   0x00000020
6338 #define NT_NOTIFY_LAST_WRITE    0x00000010
6339 #define NT_NOTIFY_SIZE          0x00000008
6340 #define NT_NOTIFY_ATTRIBUTES    0x00000004
6341 #define NT_NOTIFY_DIR_NAME      0x00000002
6342 #define NT_NOTIFY_FILE_NAME     0x00000001
6343 static const true_false_string tfs_nt_notify_stream_write = {
6344         "Notify on changes to STREAM WRITE",
6345         "Do NOT notify on changes to stream write",
6346 };
6347 static const true_false_string tfs_nt_notify_stream_size = {
6348         "Notify on changes to STREAM SIZE",
6349         "Do NOT notify on changes to stream size",
6350 };
6351 static const true_false_string tfs_nt_notify_stream_name = {
6352         "Notify on changes to STREAM NAME",
6353         "Do NOT notify on changes to stream name",
6354 };
6355 static const true_false_string tfs_nt_notify_security = {
6356         "Notify on changes to SECURITY",
6357         "Do NOT notify on changes to security",
6358 };
6359 static const true_false_string tfs_nt_notify_ea = {
6360         "Notify on changes to EA",
6361         "Do NOT notify on changes to EA",
6362 };
6363 static const true_false_string tfs_nt_notify_creation = {
6364         "Notify on changes to CREATION TIME",
6365         "Do NOT notify on changes to creation time",
6366 };
6367 static const true_false_string tfs_nt_notify_last_access = {
6368         "Notify on changes to LAST ACCESS TIME",
6369         "Do NOT notify on changes to last access time",
6370 };
6371 static const true_false_string tfs_nt_notify_last_write = {
6372         "Notify on changes to LAST WRITE TIME",
6373         "Do NOT notify on changes to last write time",
6374 };
6375 static const true_false_string tfs_nt_notify_size = {
6376         "Notify on changes to SIZE",
6377         "Do NOT notify on changes to size",
6378 };
6379 static const true_false_string tfs_nt_notify_attributes = {
6380         "Notify on changes to ATTRIBUTES",
6381         "Do NOT notify on changes to attributes",
6382 };
6383 static const true_false_string tfs_nt_notify_dir_name = {
6384         "Notify on changes to DIR NAME",
6385         "Do NOT notify on changes to dir name",
6386 };
6387 static const true_false_string tfs_nt_notify_file_name = {
6388         "Notify on changes to FILE NAME",
6389         "Do NOT notify on changes to file name",
6390 };
6391
6392 static const value_string create_disposition_vals[] = {
6393         {0,     "Supersede (supersede existing file (if it exists))"},
6394         {1,     "Open (if file exists open it, else fail)"},
6395         {2,     "Create (if file exists fail, else create it)"},
6396         {3,     "Open If (if file exists open it, else create it)"},
6397         {4,     "Overwrite (if file exists overwrite, else fail)"},
6398         {5,     "Overwrite If (if file exists overwrite, else create it)"},
6399         {0, NULL}
6400 };
6401
6402 static const value_string impersonation_level_vals[] = {
6403         {0,     "Anonymous"},
6404         {1,     "Identification"},
6405         {2,     "Impersonation"},
6406         {3,     "Delegation"},
6407         {0, NULL}
6408 };
6409
6410 static const true_false_string tfs_nt_security_flags_context_tracking = {
6411         "Security tracking mode is DYNAMIC",
6412         "Security tracking mode is STATIC",
6413 };
6414
6415 static const true_false_string tfs_nt_security_flags_effective_only = {
6416         "ONLY ENABLED aspects of the client's security context are available",
6417         "ALL aspects of the client's security context are available",
6418 };
6419
6420 static const true_false_string tfs_nt_create_bits_oplock = {
6421         "Requesting OPLOCK",
6422         "Does NOT request oplock"
6423 };
6424
6425 static const true_false_string tfs_nt_create_bits_boplock = {
6426         "Requesting BATCH OPLOCK",
6427         "Does NOT request batch oplock"
6428 };
6429
6430 /*
6431  * XXX - must be a directory, and can be a file, or can be a directory,
6432  * and must be a file?
6433  */
6434 static const true_false_string tfs_nt_create_bits_dir = {
6435         "Target of open MUST be a DIRECTORY",
6436         "Target of open can be a file"
6437 };
6438
6439 static const true_false_string tfs_nt_access_mask_generic_read = {
6440         "GENERIC READ is set",
6441         "Generic read is NOT set"
6442 };
6443 static const true_false_string tfs_nt_access_mask_generic_write = {
6444         "GENERIC WRITE is set",
6445         "Generic write is NOT set"
6446 };
6447 static const true_false_string tfs_nt_access_mask_generic_execute = {
6448         "GENERIC EXECUTE is set",
6449         "Generic execute is NOT set"
6450 };
6451 static const true_false_string tfs_nt_access_mask_generic_all = {
6452         "GENERIC ALL is set",
6453         "Generic all is NOT set"
6454 };
6455 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
6456         "MAXIMUM ALLOWED is set",
6457         "Maximum allowed is NOT set"
6458 };
6459 static const true_false_string tfs_nt_access_mask_system_security = {
6460         "SYSTEM SECURITY is set",
6461         "System security is NOT set"
6462 };
6463 static const true_false_string tfs_nt_access_mask_synchronize = {
6464         "Can wait on handle to SYNCHRONIZE on completion of I/O",
6465         "Can NOT wait on handle to synchronize on completion of I/O"
6466 };
6467 static const true_false_string tfs_nt_access_mask_write_owner = {
6468         "Can WRITE OWNER (take ownership)",
6469         "Can NOT write owner (take ownership)"
6470 };
6471 static const true_false_string tfs_nt_access_mask_write_dac = {
6472         "OWNER may WRITE the DAC",
6473         "Owner may NOT write to the DAC"
6474 };
6475 static const true_false_string tfs_nt_access_mask_read_control = {
6476         "READ ACCESS to owner, group and ACL of the SID",
6477         "Read access is NOT granted to owner, group and ACL of the SID"
6478 };
6479 static const true_false_string tfs_nt_access_mask_delete = {
6480         "DELETE access",
6481         "NO delete access"
6482 };
6483 static const true_false_string tfs_nt_access_mask_write_attributes = {
6484         "WRITE ATTRIBUTES access",
6485         "NO write attributes access"
6486 };
6487 static const true_false_string tfs_nt_access_mask_read_attributes = {
6488         "READ ATTRIBUTES access",
6489         "NO read attributes access"
6490 };
6491 static const true_false_string tfs_nt_access_mask_delete_child = {
6492         "DELETE CHILD access",
6493         "NO delete child access"
6494 };
6495 static const true_false_string tfs_nt_access_mask_execute = {
6496         "EXECUTE access",
6497         "NO execute access"
6498 };
6499 static const true_false_string tfs_nt_access_mask_write_ea = {
6500         "WRITE EXTENDED ATTRIBUTES access",
6501         "NO write extended attributes access"
6502 };
6503 static const true_false_string tfs_nt_access_mask_read_ea = {
6504         "READ EXTENDED ATTRIBUTES access",
6505         "NO read extended attributes access"
6506 };
6507 static const true_false_string tfs_nt_access_mask_append = {
6508         "APPEND access",
6509         "NO append access"
6510 };
6511 static const true_false_string tfs_nt_access_mask_write = {
6512         "WRITE access",
6513         "NO write access"
6514 };
6515 static const true_false_string tfs_nt_access_mask_read = {
6516         "READ access",
6517         "NO read access"
6518 };
6519
6520 static const true_false_string tfs_nt_share_access_delete = {
6521         "Object can be shared for DELETE",
6522         "Object can NOT be shared for delete"
6523 };
6524 static const true_false_string tfs_nt_share_access_write = {
6525         "Object can be shared for WRITE",
6526         "Object can NOT be shared for write"
6527 };
6528 static const true_false_string tfs_nt_share_access_read = {
6529         "Object can be shared for READ",
6530         "Object can NOT be shared for read"
6531 };
6532
6533 static const value_string oplock_level_vals[] = {
6534         {0,     "No oplock granted"},
6535         {1,     "Exclusive oplock granted"},
6536         {2,     "Batch oplock granted"},
6537         {3,     "Level II oplock granted"},
6538         {0, NULL}
6539 };
6540
6541 static const value_string device_type_vals[] = {
6542         {0x00000001,    "Beep"},
6543         {0x00000002,    "CDROM"},
6544         {0x00000003,    "CDROM Filesystem"},
6545         {0x00000004,    "Controller"},
6546         {0x00000005,    "Datalink"},
6547         {0x00000006,    "Dfs"},
6548         {0x00000007,    "Disk"},
6549         {0x00000008,    "Disk Filesystem"},
6550         {0x00000009,    "Filesystem"},
6551         {0x0000000a,    "Inport Port"},
6552         {0x0000000b,    "Keyboard"},
6553         {0x0000000c,    "Mailslot"},
6554         {0x0000000d,    "MIDI-In"},
6555         {0x0000000e,    "MIDI-Out"},
6556         {0x0000000f,    "Mouse"},
6557         {0x00000010,    "Multi UNC Provider"},
6558         {0x00000011,    "Named Pipe"},
6559         {0x00000012,    "Network"},
6560         {0x00000013,    "Network Browser"},
6561         {0x00000014,    "Network Filesystem"},
6562         {0x00000015,    "NULL"},
6563         {0x00000016,    "Parallel Port"},
6564         {0x00000017,    "Physical card"},
6565         {0x00000018,    "Printer"},
6566         {0x00000019,    "Scanner"},
6567         {0x0000001a,    "Serial Mouse port"},
6568         {0x0000001b,    "Serial port"},
6569         {0x0000001c,    "Screen"},
6570         {0x0000001d,    "Sound"},
6571         {0x0000001e,    "Streams"},
6572         {0x0000001f,    "Tape"},
6573         {0x00000020,    "Tape Filesystem"},
6574         {0x00000021,    "Transport"},
6575         {0x00000022,    "Unknown"},
6576         {0x00000023,    "Video"},
6577         {0x00000024,    "Virtual Disk"},
6578         {0x00000025,    "WAVE-In"},
6579         {0x00000026,    "WAVE-Out"},
6580         {0x00000027,    "8042 Port"},
6581         {0x00000028,    "Network Redirector"},
6582         {0x00000029,    "Battery"},
6583         {0x0000002a,    "Bus Extender"},
6584         {0x0000002b,    "Modem"},
6585         {0x0000002c,    "VDM"},
6586         {0,     NULL}
6587 };
6588
6589 static const value_string is_directory_vals[] = {
6590         {0,     "This is NOT a directory"},
6591         {1,     "This is a DIRECTORY"},
6592         {0, NULL}
6593 };
6594
6595 typedef struct _nt_trans_data {
6596         int subcmd;
6597         guint32 sd_len;
6598         guint32 ea_len;
6599 } nt_trans_data;
6600
6601
6602
6603 static int
6604 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6605 {
6606         guint8 mask;
6607         proto_item *item = NULL;
6608         proto_tree *tree = NULL;
6609
6610         mask = tvb_get_guint8(tvb, offset);
6611
6612         if(parent_tree){
6613                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6614                         "Security Flags: 0x%02x", mask);
6615                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
6616         }
6617
6618         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
6619                 tvb, offset, 1, mask);
6620         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
6621                 tvb, offset, 1, mask);
6622
6623         offset += 1;
6624
6625         return offset;
6626 }
6627
6628 static int
6629 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6630 {
6631         guint32 mask;
6632         proto_item *item = NULL;
6633         proto_tree *tree = NULL;
6634
6635         mask = tvb_get_letohl(tvb, offset);
6636
6637         if(parent_tree){
6638                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6639                         "Share Access: 0x%08x", mask);
6640                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
6641         }
6642
6643         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
6644                 tvb, offset, 4, mask);
6645         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
6646                 tvb, offset, 4, mask);
6647         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
6648                 tvb, offset, 4, mask);
6649
6650         offset += 4;
6651
6652         return offset;
6653 }
6654
6655
6656 static int
6657 dissect_nt_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6658 {
6659         guint32 mask;
6660         proto_item *item = NULL;
6661         proto_tree *tree = NULL;
6662
6663         mask = tvb_get_letohl(tvb, offset);
6664
6665         if(parent_tree){
6666                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6667                         "Access Mask: 0x%08x", mask);
6668                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
6669         }
6670
6671         /*
6672          * Some of these bits come from
6673          *
6674          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6675          *
6676          * and others come from the section on ZwOpenFile in "Windows(R)
6677          * NT(R)/2000 Native API Reference".
6678          */
6679         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
6680                 tvb, offset, 4, mask);
6681         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
6682                 tvb, offset, 4, mask);
6683         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
6684                 tvb, offset, 4, mask);
6685         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
6686                 tvb, offset, 4, mask);
6687         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
6688                 tvb, offset, 4, mask);
6689         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
6690                 tvb, offset, 4, mask);
6691         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
6692                 tvb, offset, 4, mask);
6693         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
6694                 tvb, offset, 4, mask);
6695         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
6696                 tvb, offset, 4, mask);
6697         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
6698                 tvb, offset, 4, mask);
6699         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
6700                 tvb, offset, 4, mask);
6701         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
6702                 tvb, offset, 4, mask);
6703         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
6704                 tvb, offset, 4, mask);
6705         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
6706                 tvb, offset, 4, mask);
6707         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
6708                 tvb, offset, 4, mask);
6709         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
6710                 tvb, offset, 4, mask);
6711         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
6712                 tvb, offset, 4, mask);
6713         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
6714                 tvb, offset, 4, mask);
6715         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
6716                 tvb, offset, 4, mask);
6717         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
6718                 tvb, offset, 4, mask);
6719
6720         offset += 4;
6721
6722         return offset;
6723 }
6724
6725 static int
6726 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6727 {
6728         guint32 mask;
6729         proto_item *item = NULL;
6730         proto_tree *tree = NULL;
6731
6732         mask = tvb_get_letohl(tvb, offset);
6733
6734         if(parent_tree){
6735                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6736                         "Create Flags: 0x%08x", mask);
6737                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
6738         }
6739
6740         /*
6741          * XXX - it's 0x00000016 in at least one capture, but
6742          * Network Monitor doesn't say what the 0x00000010 bit is.
6743          * Does the Win32 API documentation, or NT Native API book,
6744          * suggest anything?
6745          */
6746         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
6747                 tvb, offset, 4, mask);
6748         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
6749                 tvb, offset, 4, mask);
6750         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
6751                 tvb, offset, 4, mask);
6752
6753         offset += 4;
6754
6755         return offset;
6756 }
6757
6758 /*
6759  * XXX - there are some more flags in the description of "ZwOpenFile()"
6760  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
6761  * the wire as well?  (The spec at
6762  *
6763  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6764  *
6765  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
6766  * via the SMB protocol.  The NT redirector should convert this option
6767  * to FILE_WRITE_THROUGH."
6768  *
6769  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
6770  * values one would infer from their position in the list of flags for
6771  * "ZwOpenFile()".  Most of the others probably have those values
6772  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
6773  * which might go over the wire (for the benefit of backup/restore software).
6774  */
6775 static const true_false_string tfs_nt_create_options_directory = {
6776         "File being created/opened must be a directory",
6777         "File being created/opened must not be a directory"
6778 };
6779 static const true_false_string tfs_nt_create_options_write_through = {
6780         "Writes should flush buffered data before completing",
6781         "Writes need not flush buffered data before completing"
6782 };
6783 static const true_false_string tfs_nt_create_options_sequential_only = {
6784         "The file will only be accessed sequentially",
6785         "The file might not only be accessed sequentially"
6786 };
6787 static const true_false_string tfs_nt_create_options_sync_io_alert = {
6788         "All operations SYNCHRONOUS, waits subject to termination from alert",
6789         "Operations NOT necessarily synchronous"
6790 };
6791 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
6792         "All operations SYNCHRONOUS, waits not subject to alert",
6793         "Operations NOT necessarily synchronous"
6794 };
6795 static const true_false_string tfs_nt_create_options_non_directory = {
6796         "File being created/opened must not be a directory",
6797         "File being created/opened must be a directory"
6798 };
6799 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
6800         "The client does not understand extended attributes",
6801         "The client understands extended attributes"
6802 };
6803 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
6804         "The client understands only 8.3 file names",
6805         "The client understands long file names"
6806 };
6807 static const true_false_string tfs_nt_create_options_random_access = {
6808         "The file will be accessed randomly",
6809         "The file will not be accessed randomly"
6810 };
6811 static const true_false_string tfs_nt_create_options_delete_on_close = {
6812         "The file should be deleted when it is closed",
6813         "The file should not be deleted when it is closed"
6814 };
6815
6816 static int
6817 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6818 {
6819         guint32 mask;
6820         proto_item *item = NULL;
6821         proto_tree *tree = NULL;
6822
6823         mask = tvb_get_letohl(tvb, offset);
6824
6825         if(parent_tree){
6826                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6827                         "Create Options: 0x%08x", mask);
6828                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
6829         }
6830
6831         /*
6832          * From
6833          *
6834          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6835          */
6836         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
6837                 tvb, offset, 4, mask);
6838         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
6839                 tvb, offset, 4, mask);
6840         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
6841                 tvb, offset, 4, mask);
6842         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
6843                 tvb, offset, 4, mask);
6844         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
6845                 tvb, offset, 4, mask);
6846         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
6847                 tvb, offset, 4, mask);
6848         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
6849                 tvb, offset, 4, mask);
6850         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
6851                 tvb, offset, 4, mask);
6852         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
6853                 tvb, offset, 4, mask);
6854         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
6855                 tvb, offset, 4, mask);
6856
6857         offset += 4;
6858
6859         return offset;
6860 }
6861
6862 static int
6863 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6864 {
6865         guint32 mask;
6866         proto_item *item = NULL;
6867         proto_tree *tree = NULL;
6868
6869         mask = tvb_get_letohl(tvb, offset);
6870
6871         if(parent_tree){
6872                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6873                         "Completion Filter: 0x%08x", mask);
6874                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
6875         }
6876
6877         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
6878                 tvb, offset, 4, mask);
6879         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
6880                 tvb, offset, 4, mask);
6881         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
6882                 tvb, offset, 4, mask);
6883         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
6884                 tvb, offset, 4, mask);
6885         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
6886                 tvb, offset, 4, mask);
6887         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
6888                 tvb, offset, 4, mask);
6889         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
6890                 tvb, offset, 4, mask);
6891         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
6892                 tvb, offset, 4, mask);
6893         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
6894                 tvb, offset, 4, mask);
6895         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
6896                 tvb, offset, 4, mask);
6897         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
6898                 tvb, offset, 4, mask);
6899         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
6900                 tvb, offset, 4, mask);
6901
6902         offset += 4;
6903         return offset;
6904 }
6905
6906 static int
6907 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6908 {
6909         guint8 mask;
6910         proto_item *item = NULL;
6911         proto_tree *tree = NULL;
6912
6913         mask = tvb_get_guint8(tvb, offset);
6914
6915         if(parent_tree){
6916                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6917                         "Completion Filter: 0x%02x", mask);
6918                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
6919         }
6920
6921         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
6922                 tvb, offset, 1, mask);
6923
6924         offset += 1;
6925         return offset;
6926 }
6927
6928 /*
6929  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
6930  * Native API Reference".
6931  */
6932 static const true_false_string tfs_nt_qsd_owner = {
6933         "Requesting OWNER security information",
6934         "NOT requesting owner security information",
6935 };
6936
6937 static const true_false_string tfs_nt_qsd_group = {
6938         "Requesting GROUP security information",
6939         "NOT requesting group security information",
6940 };
6941
6942 static const true_false_string tfs_nt_qsd_dacl = {
6943         "Requesting DACL security information",
6944         "NOT requesting DACL security information",
6945 };
6946
6947 static const true_false_string tfs_nt_qsd_sacl = {
6948         "Requesting SACL security information",
6949         "NOT requesting SACL security information",
6950 };
6951
6952 #define NT_QSD_OWNER    0x00000001
6953 #define NT_QSD_GROUP    0x00000002
6954 #define NT_QSD_DACL     0x00000004
6955 #define NT_QSD_SACL     0x00000008
6956
6957 static int
6958 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6959 {
6960         guint32 mask;
6961         proto_item *item = NULL;
6962         proto_tree *tree = NULL;
6963
6964         mask = tvb_get_letohl(tvb, offset);
6965
6966         if(parent_tree){
6967                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6968                         "Security Information: 0x%08x", mask);
6969                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
6970         }
6971
6972         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
6973                 tvb, offset, 4, mask);
6974         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
6975                 tvb, offset, 4, mask);
6976         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
6977                 tvb, offset, 4, mask);
6978         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
6979                 tvb, offset, 4, mask);
6980
6981         offset += 4;
6982
6983         return offset;
6984 }
6985
6986 static void
6987 free_g_string(void *arg)
6988 {
6989         g_string_free(arg, TRUE);
6990 }
6991
6992 int
6993 dissect_nt_sid(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name)
6994 {
6995         proto_item *item = NULL;
6996         proto_tree *tree = NULL;
6997         int old_offset = offset, sa_offset = offset;
6998         guint rid;
6999         guint8 revision;
7000         guint8 num_auth;
7001         guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
7002         int i;
7003         GString *gstr;
7004
7005         if(parent_tree){
7006                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7007                                            "NT %s SID", name);
7008                 tree = proto_item_add_subtree(item, ett_smb_sid);
7009         }
7010
7011         /* revision of sid */
7012         revision = tvb_get_guint8(tvb, offset);
7013         proto_tree_add_item(tree, hf_smb_sid_revision, tvb, offset, 1, TRUE);
7014         offset += 1;
7015
7016         switch(revision){
7017         case 1:
7018         case 2:  /* Not sure what the different revision numbers mean */
7019           /* number of authorities*/
7020           num_auth = tvb_get_guint8(tvb, offset);
7021           proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, offset, 1, TRUE);
7022           offset += 1;
7023
7024           /* XXX perhaps we should have these thing searchable?
7025              a new FT_xxx thingie? SMB is quite common!*/
7026           /* identifier authorities */
7027
7028           for(i=0;i<6;i++){
7029             auth = (auth << 8) + tvb_get_guint8(tvb, offset);
7030
7031             offset++;
7032           }
7033
7034           proto_tree_add_text(tree, tvb, offset - 6, 6, "Authority: %u", auth);
7035
7036           sa_offset = offset;
7037
7038           gstr = g_string_new("");
7039
7040           CLEANUP_PUSH(free_g_string, gstr);
7041
7042           /* sub authorities, leave RID to last */
7043           for(i=0; i < (num_auth > 4?(num_auth - 1):num_auth); i++){
7044             /*
7045              * XXX should not be letohl but native byteorder according to
7046              * Samba header files.
7047              *
7048              * However, considering that there were never any NT ports
7049              * to big-endian platforms (PowerPC and MIPS ran little-endian,
7050              * and IA-64 runs little-endian, as does x86-64), we can (?)
7051              * assume that non le byte encodings will be "uncommon"?
7052              */
7053              g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"),
7054                   tvb_get_letohl(tvb, offset));
7055              offset+=4;
7056           }
7057
7058           proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
7059
7060           if (num_auth > 4) {
7061             rid = tvb_get_letohl(tvb, offset);
7062             proto_tree_add_text(tree, tvb, offset, 4, "RID: %u", rid);
7063             proto_item_append_text(item, ": S-1-%u-%s-%u", auth, gstr->str, rid);
7064             offset+=4;
7065           }
7066           else {
7067             proto_item_append_text(item, ": S-1-%u-%s", auth, gstr->str);
7068           }
7069
7070           CLEANUP_CALL_AND_POP;
7071
7072         }
7073
7074         proto_item_set_len(item, offset-old_offset);
7075         return offset;
7076 }
7077
7078
7079 static const value_string ace_type_vals[] = {
7080   { 0, "Access Allowed"},
7081   { 1, "Access Denied"},
7082   { 2, "System Audit"},
7083   { 3, "System Alarm"},
7084   { 0, NULL}
7085 };
7086 static const true_false_string tfs_ace_flags_object_inherit = {
7087   "Subordinate files will inherit this ACE",
7088   "Subordinate files will not inherit this ACE"
7089 };
7090 static const true_false_string tfs_ace_flags_container_inherit = {
7091   "Subordinate containers will inherit this ACE",
7092   "Subordinate containers will not inherit this ACE"
7093 };
7094 static const true_false_string tfs_ace_flags_non_propagate_inherit = {
7095   "Subordinate object will not propagate the inherited ACE further",
7096   "Subordinate object will propagate the inherited ACE further"
7097 };
7098 static const true_false_string tfs_ace_flags_inherit_only = {
7099   "This ACE does not apply to the current object",
7100   "This ACE applies to the current object"
7101 };
7102 static const true_false_string tfs_ace_flags_inherited_ace = {
7103   "This ACE was inherited from its parent object",
7104   "This ACE was not inherited from its parent object"
7105 };
7106 static const true_false_string tfs_ace_flags_successful_access = {
7107   "Successful accesses will be audited",
7108   "Successful accesses will not be audited"
7109 };
7110 static const true_false_string tfs_ace_flags_failed_access = {
7111   "Failed accesses will be audited",
7112   "Failed accesses will not be audited"
7113 };
7114
7115 #define APPEND_ACE_TEXT(flag, item, string) \
7116         if(flag){                                                       \
7117                 if(item)                                                \
7118                         proto_item_append_text(item, string, sep);      \
7119                 sep = ", ";                                             \
7120         }
7121
7122 static int
7123 dissect_nt_v2_ace_flags(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7124 {
7125         proto_item *item = NULL;
7126         proto_tree *tree = NULL;
7127         guint8 mask;
7128         char *sep = " ";
7129
7130         mask = tvb_get_guint8(tvb, offset);
7131         if(parent_tree){
7132                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7133                                            "NT ACE Flags: 0x%02x", mask);
7134                 tree = proto_item_add_subtree(item, ett_smb_ace_flags);
7135         }
7136
7137         proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
7138                        tvb, offset, 1, mask);
7139         APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
7140
7141         proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
7142                        tvb, offset, 1, mask);
7143         APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
7144
7145         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
7146                        tvb, offset, 1, mask);
7147         APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
7148
7149         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
7150                        tvb, offset, 1, mask);
7151         APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
7152
7153         proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
7154                        tvb, offset, 1, mask);
7155         APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
7156
7157         proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
7158                        tvb, offset, 1, mask);
7159         APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
7160
7161         proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
7162                        tvb, offset, 1, mask);
7163         APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
7164
7165
7166         offset += 1;
7167         return offset;
7168 }
7169
7170 static int
7171 dissect_nt_v2_ace(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7172 {
7173         proto_item *item = NULL;
7174         proto_tree *tree = NULL;
7175         int old_offset = offset;
7176         guint16 size;
7177
7178         if(parent_tree){
7179                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7180                                            "NT ACE: ");
7181                 tree = proto_item_add_subtree(item, ett_smb_ace);
7182         }
7183
7184         /* type */
7185         if(item){
7186           proto_item_append_text(item, val_to_str(tvb_get_guint8(tvb, offset), ace_type_vals, "Unknown ACE type (%u)"));
7187         }
7188         proto_tree_add_item(tree, hf_smb_ace_type, tvb, offset, 1, TRUE);
7189         offset += 1;
7190
7191         /* flags */
7192         offset = dissect_nt_v2_ace_flags(tvb, offset, tree);
7193
7194         /* size */
7195         size = tvb_get_letohs(tvb, offset);
7196         proto_tree_add_uint(tree, hf_smb_ace_size, tvb, offset, 2, size);
7197         offset += 2;
7198
7199         /* access mask */
7200         offset = dissect_nt_access_mask(tvb, tree, offset);
7201
7202         /* SID */
7203         offset = dissect_nt_sid(tvb, offset, tree, "ACE");
7204
7205         proto_item_set_len(item, offset-old_offset);
7206
7207         /* Sometimes there is some spare space at the end of the ACE so use
7208            the size field to work out where the end is. */
7209
7210         return old_offset + size;
7211 }
7212
7213 static int
7214 dissect_nt_acl(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name)
7215 {
7216         proto_item *item = NULL;
7217         proto_tree *tree = NULL;
7218         int old_offset = offset;
7219         guint16 revision;
7220         guint32 num_aces;
7221
7222         if(parent_tree){
7223                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7224                                            "NT %s ACL", name);
7225                 tree = proto_item_add_subtree(item, ett_smb_acl);
7226         }
7227
7228         /* revision */
7229         revision = tvb_get_letohs(tvb, offset);
7230         proto_tree_add_uint(tree, hf_smb_acl_revision,
7231                 tvb, offset, 2, revision);
7232         offset += 2;
7233
7234         switch(revision){
7235         case 2:  /* only version we will ever see of this structure?*/
7236         case 3:
7237           /* size */
7238           proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
7239           offset += 2;
7240
7241           /* number of ace structures */
7242           num_aces = tvb_get_letohl(tvb, offset);
7243           proto_tree_add_uint(tree, hf_smb_acl_num_aces,
7244                               tvb, offset, 4, num_aces);
7245           offset += 4;
7246
7247           while(num_aces--){
7248             offset=dissect_nt_v2_ace(tvb, offset, tree);
7249           }
7250         }
7251
7252         proto_item_set_len(item, offset-old_offset);
7253         return offset;
7254 }
7255
7256 static const true_false_string tfs_sec_desc_type_owner_defaulted = {
7257   "OWNER is DEFAULTED",
7258   "Owner is NOT defaulted"
7259 };
7260 static const true_false_string tfs_sec_desc_type_group_defaulted = {
7261   "GROUP is DEFAULTED",
7262   "Group is NOT defaulted"
7263 };
7264 static const true_false_string tfs_sec_desc_type_dacl_present = {
7265   "DACL is PRESENT",
7266   "DACL is NOT present"
7267 };
7268 static const true_false_string tfs_sec_desc_type_dacl_defaulted = {
7269   "DACL is DEFAULTED",
7270   "DACL is NOT defaulted"
7271 };
7272 static const true_false_string tfs_sec_desc_type_sacl_present = {
7273   "SACL is PRESENT",
7274   "SACL is NOT present"
7275 };
7276 static const true_false_string tfs_sec_desc_type_sacl_defaulted = {
7277   "SACL is DEFAULTED",
7278   "SACL is NOT defaulted"
7279 };
7280 static const true_false_string tfs_sec_desc_type_dacl_auto_inherit_req = {
7281   "DACL has AUTO INHERIT REQUIRED",
7282   "DACL does NOT require auto inherit"
7283 };
7284 static const true_false_string tfs_sec_desc_type_sacl_auto_inherit_req = {
7285   "SACL has AUTO INHERIT REQUIRED",
7286   "SACL does NOT require auto inherit"
7287 };
7288 static const true_false_string tfs_sec_desc_type_dacl_auto_inherited = {
7289   "DACL is AUTO INHERITED",
7290   "DACL is NOT auto inherited"
7291 };
7292 static const true_false_string tfs_sec_desc_type_sacl_auto_inherited = {
7293   "SACL is AUTO INHERITED",
7294   "SACL is NOT auto inherited"
7295 };
7296 static const true_false_string tfs_sec_desc_type_dacl_protected = {
7297   "The DACL is PROTECTED",
7298   "The DACL is NOT protected"
7299 };
7300 static const true_false_string tfs_sec_desc_type_sacl_protected = {
7301   "The SACL is PROTECTED",
7302   "The SACL is NOT protected"
7303 };
7304 static const true_false_string tfs_sec_desc_type_self_relative = {
7305   "This SecDesc is SELF RELATIVE",
7306   "This SecDesc is NOT self relative"
7307 };
7308
7309
7310 static int
7311 dissect_nt_sec_desc_type(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7312 {
7313         proto_item *item = NULL;
7314         proto_tree *tree = NULL;
7315         guint16 mask;
7316
7317         mask = tvb_get_letohs(tvb, offset);
7318         if(parent_tree){
7319                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7320                                            "Type: 0x%04x", mask);
7321                 tree = proto_item_add_subtree(item, ett_smb_sec_desc_type);
7322         }
7323
7324         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_self_relative,
7325                                tvb, offset, 2, mask);
7326         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_protected,
7327                                tvb, offset, 2, mask);
7328         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_protected,
7329                                tvb, offset, 2, mask);
7330         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherited,
7331                                tvb, offset, 2, mask);
7332         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherited,
7333                                tvb, offset, 2, mask);
7334         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherit_req,
7335                                tvb, offset, 2, mask);
7336         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherit_req,
7337                                tvb, offset, 2, mask);
7338         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_defaulted,
7339                                tvb, offset, 2, mask);
7340         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_present,
7341                                tvb, offset, 2, mask);
7342         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_defaulted,
7343                                tvb, offset, 2, mask);
7344         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_present,
7345                                tvb, offset, 2, mask);
7346         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_group_defaulted,
7347                                tvb, offset, 2, mask);
7348         proto_tree_add_boolean(tree, hf_smb_sec_desc_type_owner_defaulted,
7349                                tvb, offset, 2, mask);
7350
7351
7352         offset += 2;
7353         return offset;
7354 }
7355
7356 int
7357 dissect_nt_sec_desc(tvbuff_t *tvb, int offset, proto_tree *parent_tree, int len)
7358 {
7359         proto_item *item = NULL;
7360         proto_tree *tree = NULL;
7361         guint16 revision;
7362         int old_offset = offset;
7363         guint32 owner_sid_offset;
7364         guint32 group_sid_offset;
7365         guint32 sacl_offset;
7366         guint32 dacl_offset;
7367
7368         if(parent_tree){
7369                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7370                                            "NT Security Descriptor");
7371                 tree = proto_item_add_subtree(item, ett_smb_sec_desc);
7372         }
7373
7374         /* revision */
7375         revision = tvb_get_letohs(tvb, offset);
7376         proto_tree_add_uint(tree, hf_smb_sec_desc_revision,
7377                 tvb, offset, 2, revision);
7378         offset += 2;
7379
7380         switch(revision){
7381         case 1:  /* only version we will ever see of this structure?*/
7382           /* type */
7383           offset = dissect_nt_sec_desc_type(tvb, offset, tree);
7384
7385           /* offset to owner sid */
7386           owner_sid_offset = tvb_get_letohl(tvb, offset);
7387           proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %d", owner_sid_offset);
7388           offset += 4;
7389
7390           /* offset to group sid */
7391           group_sid_offset = tvb_get_letohl(tvb, offset);
7392           proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %d", group_sid_offset);
7393           offset += 4;
7394
7395           /* offset to sacl */
7396           sacl_offset = tvb_get_letohl(tvb, offset);
7397           proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %d", sacl_offset);
7398           offset += 4;
7399
7400           /* offset to dacl */
7401           dacl_offset = tvb_get_letohl(tvb, offset);
7402           proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %d", dacl_offset);
7403           offset += 4;
7404
7405           /*owner SID*/
7406           if(owner_sid_offset){
7407             if (len == -1)
7408               offset = dissect_nt_sid(tvb, offset, tree, "Owner");
7409             else
7410               dissect_nt_sid(tvb, old_offset+owner_sid_offset, tree, "Owner");
7411           }
7412
7413           /*group SID*/
7414           if(group_sid_offset){
7415             dissect_nt_sid(tvb, old_offset+group_sid_offset, tree, "Group");
7416           }
7417
7418           /* sacl */
7419           if(sacl_offset){
7420             dissect_nt_acl(tvb, old_offset+sacl_offset, tree, "System (SACL)");
7421           }
7422
7423           /* dacl */
7424           if(dacl_offset){
7425             dissect_nt_acl(tvb, old_offset+dacl_offset, tree, "User (DACL)");
7426           }
7427
7428         }
7429
7430         return offset+len;
7431 }
7432
7433 static int
7434 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
7435 {
7436         int old_offset, old_sid_offset;
7437         guint32 qsize;
7438
7439         do {
7440                 old_offset=offset;
7441
7442                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7443                 qsize=tvb_get_letohl(tvb, offset);
7444                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
7445                 COUNT_BYTES_TRANS_SUBR(4);
7446
7447                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7448                 /* length of SID */
7449                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7450                 COUNT_BYTES_TRANS_SUBR(4);
7451
7452                 /* 16 unknown bytes */
7453                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7454                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7455                             offset, 8, TRUE);
7456                 COUNT_BYTES_TRANS_SUBR(8);
7457
7458                 /* number of bytes for used quota */
7459                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7460                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
7461                 COUNT_BYTES_TRANS_SUBR(8);
7462
7463                 /* number of bytes for quota warning */
7464                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7465                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
7466                 COUNT_BYTES_TRANS_SUBR(8);
7467
7468                 /* number of bytes for quota limit */
7469                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7470                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
7471                 COUNT_BYTES_TRANS_SUBR(8);
7472
7473                 /* SID of the user */
7474                 old_sid_offset=offset;
7475                 offset = dissect_nt_sid(tvb, offset, tree, "Quota");
7476                 *bcp -= (offset-old_sid_offset);
7477
7478                 if(qsize){
7479                         offset = old_offset+qsize;
7480                 }
7481         }while(qsize);
7482
7483
7484         return offset;
7485 }
7486
7487
7488 static int
7489 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
7490 {
7491         proto_item *item = NULL;
7492         proto_tree *tree = NULL;
7493         smb_info_t *si;
7494         int old_offset = offset;
7495         guint16 bcp=bc; /* XXX fixme */
7496
7497         si = (smb_info_t *)pinfo->private_data;
7498
7499         if(parent_tree){
7500                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
7501                                 "%s Data",
7502                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7503                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7504         }
7505
7506         switch(ntd->subcmd){
7507         case NT_TRANS_CREATE:
7508                 /* security descriptor */
7509                 if(ntd->sd_len){
7510                         offset = dissect_nt_sec_desc(tvb, offset, tree, ntd->sd_len);
7511                 }
7512
7513                 /* extended attributes */
7514                 if(ntd->ea_len){
7515                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
7516                         offset += ntd->ea_len;
7517                 }
7518
7519                 break;
7520         case NT_TRANS_IOCTL:
7521                 /* ioctl data */
7522                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
7523                 offset += bc;
7524
7525                 break;
7526         case NT_TRANS_SSD:
7527                 offset = dissect_nt_sec_desc(tvb, offset, tree, bc);
7528                 break;
7529         case NT_TRANS_NOTIFY:
7530                 break;
7531         case NT_TRANS_RENAME:
7532                 /* XXX not documented */
7533                 break;
7534         case NT_TRANS_QSD:
7535                 break;
7536         case NT_TRANS_GET_USER_QUOTA:
7537                 /* unknown 4 bytes */
7538                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7539                             offset, 4, TRUE);
7540                 offset += 4;
7541
7542                 /* length of SID */
7543                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7544                 offset +=4;
7545
7546                 offset = dissect_nt_sid(tvb, offset, tree, "Quota");
7547                 break;
7548         case NT_TRANS_SET_USER_QUOTA:
7549                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
7550                 break;
7551         }
7552
7553         /* ooops there were data we didnt know how to process */
7554         if((offset-old_offset) < bc){
7555                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
7556                     bc - (offset-old_offset), TRUE);
7557                 offset += bc - (offset-old_offset);
7558         }
7559
7560         return offset;
7561 }
7562
7563 static int
7564 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)
7565 {
7566         proto_item *item = NULL;
7567         proto_tree *tree = NULL;
7568         smb_info_t *si;
7569         guint32 fn_len;
7570         const char *fn;
7571
7572         si = (smb_info_t *)pinfo->private_data;
7573
7574         if(parent_tree){
7575                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7576                                 "%s Parameters",
7577                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7578                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7579         }
7580
7581         switch(ntd->subcmd){
7582         case NT_TRANS_CREATE:
7583                 /* Create flags */
7584                 offset = dissect_nt_create_bits(tvb, tree, offset);
7585                 bc -= 4;
7586
7587                 /* root directory fid */
7588                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
7589                 COUNT_BYTES(4);
7590
7591                 /* nt access mask */
7592                 offset = dissect_nt_access_mask(tvb, tree, offset);
7593                 bc -= 4;
7594
7595                 /* allocation size */
7596                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7597                 COUNT_BYTES(8);
7598
7599                 /* Extended File Attributes */
7600                 offset = dissect_file_ext_attr(tvb, tree, offset);
7601                 bc -= 4;
7602
7603                 /* share access */
7604                 offset = dissect_nt_share_access(tvb, tree, offset);
7605                 bc -= 4;
7606
7607                 /* create disposition */
7608                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
7609                 COUNT_BYTES(4);
7610
7611                 /* create options */
7612                 offset = dissect_nt_create_options(tvb, tree, offset);
7613                 bc -= 4;
7614
7615                 /* sd length */
7616                 ntd->sd_len = tvb_get_letohl(tvb, offset);
7617                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
7618                 COUNT_BYTES(4);
7619
7620                 /* ea length */
7621                 ntd->ea_len = tvb_get_letohl(tvb, offset);
7622                 proto_tree_add_uint(tree, hf_smb_ea_length, tvb, offset, 4, ntd->ea_len);
7623                 COUNT_BYTES(4);
7624
7625                 /* file name len */
7626                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
7627                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
7628                 COUNT_BYTES(4);
7629
7630                 /* impersonation level */
7631                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
7632                 COUNT_BYTES(4);
7633
7634                 /* security flags */
7635                 offset = dissect_nt_security_flags(tvb, tree, offset);
7636                 bc -= 1;
7637
7638                 /* file name */
7639                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
7640                 if (fn != NULL) {
7641                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7642                                 fn);
7643                         COUNT_BYTES(fn_len);
7644                 }
7645
7646                 break;
7647         case NT_TRANS_IOCTL:
7648                 break;
7649         case NT_TRANS_SSD: {
7650                 guint16 fid;
7651
7652                 /* fid */
7653                 fid = tvb_get_letohs(tvb, offset);
7654                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7655                 offset += 2;
7656
7657                 /* 2 reserved bytes */
7658                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7659                 offset += 2;
7660
7661                 /* security information */
7662                 offset = dissect_security_information_mask(tvb, tree, offset);
7663                 break;
7664         }
7665         case NT_TRANS_NOTIFY:
7666                 break;
7667         case NT_TRANS_RENAME:
7668                 /* XXX not documented */
7669                 break;
7670         case NT_TRANS_QSD: {
7671                 guint16 fid;
7672
7673                 /* fid */
7674                 fid = tvb_get_letohs(tvb, offset);
7675                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7676                 offset += 2;
7677
7678                 /* 2 reserved bytes */
7679                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7680                 offset += 2;
7681
7682                 /* security information */
7683                 offset = dissect_security_information_mask(tvb, tree, offset);
7684                 break;
7685         }
7686         case NT_TRANS_GET_USER_QUOTA:
7687                 /* not decoded yet */
7688                 break;
7689         case NT_TRANS_SET_USER_QUOTA:
7690                 /* not decoded yet */
7691                 break;
7692         }
7693
7694         return offset;
7695 }
7696
7697 static int
7698 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7699 {
7700         proto_item *item = NULL;
7701         proto_tree *tree = NULL;
7702         smb_info_t *si;
7703         int old_offset = offset;
7704
7705         si = (smb_info_t *)pinfo->private_data;
7706
7707         if(parent_tree){
7708                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7709                                 "%s Setup",
7710                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7711                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
7712         }
7713
7714         switch(ntd->subcmd){
7715         case NT_TRANS_CREATE:
7716                 break;
7717         case NT_TRANS_IOCTL: {
7718                 guint16 fid;
7719
7720                 /* function code */
7721                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
7722                 offset += 4;
7723
7724                 /* fid */
7725                 fid = tvb_get_letohs(tvb, offset);
7726                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7727                 offset += 2;
7728
7729                 /* isfsctl */
7730                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
7731                 offset += 1;
7732
7733                 /* isflags */
7734                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
7735
7736                 break;
7737         }
7738         case NT_TRANS_SSD:
7739                 break;
7740         case NT_TRANS_NOTIFY: {
7741                 guint16 fid;
7742
7743                 /* completion filter */
7744                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
7745
7746                 /* fid */
7747                 fid = tvb_get_letohs(tvb, offset);
7748                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7749                 offset += 2;
7750
7751                 /* watch tree */
7752                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
7753                 offset += 1;
7754
7755                 /* reserved byte */
7756                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7757                 offset += 1;
7758
7759                 break;
7760         }
7761         case NT_TRANS_RENAME:
7762                 /* XXX not documented */
7763                 break;
7764         case NT_TRANS_QSD:
7765                 break;
7766         case NT_TRANS_GET_USER_QUOTA:
7767                 /* not decoded yet */
7768                 break;
7769         case NT_TRANS_SET_USER_QUOTA:
7770                 /* not decoded yet */
7771                 break;
7772         }
7773
7774         return old_offset+len;
7775 }
7776
7777
7778 static int
7779 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
7780 {
7781         guint8 wc, sc;
7782         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
7783         smb_info_t *si;
7784         smb_saved_info_t *sip;
7785         int subcmd;
7786         nt_trans_data ntd;
7787         guint16 bc;
7788         int padcnt;
7789         smb_nt_transact_info_t *nti;
7790
7791         si = (smb_info_t *)pinfo->private_data;
7792         sip = si->sip;
7793
7794         WORD_COUNT;
7795
7796         if(wc>=19){
7797                 /* primary request */
7798                 /* max setup count */
7799                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
7800                 offset += 1;
7801
7802                 /* 2 reserved bytes */
7803                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7804                 offset += 2;
7805         } else {
7806                 /* secondary request */
7807                 /* 3 reserved bytes */
7808                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
7809                 offset += 3;
7810         }
7811
7812
7813         /* total param count */
7814         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
7815         offset += 4;
7816
7817         /* total data count */
7818         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
7819         offset += 4;
7820
7821         if(wc>=19){
7822                 /* primary request */
7823                 /* max param count */
7824                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
7825                 offset += 4;
7826
7827                 /* max data count */
7828                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
7829                 offset += 4;
7830         }
7831
7832         /* param count */
7833         pc = tvb_get_letohl(tvb, offset);
7834         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
7835         offset += 4;
7836
7837         /* param offset */
7838         po = tvb_get_letohl(tvb, offset);
7839         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
7840         offset += 4;
7841
7842         /* param displacement */
7843         if(wc>=19){
7844                 /* primary request*/
7845                 pd = 0;
7846         } else {
7847                 /* secondary request */
7848                 pd = tvb_get_letohl(tvb, offset);
7849                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
7850                 offset += 4;
7851         }
7852
7853         /* data count */
7854         dc = tvb_get_letohl(tvb, offset);
7855         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
7856         offset += 4;
7857
7858         /* data offset */
7859         od = tvb_get_letohl(tvb, offset);
7860         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
7861         offset += 4;
7862
7863         /* data displacement */
7864         if(wc>=19){
7865                 /* primary request */
7866                 dd = 0;
7867         } else {
7868                 /* secondary request */
7869                 dd = tvb_get_letohl(tvb, offset);
7870                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
7871                 offset += 4;
7872         }
7873
7874         /* setup count */
7875         if(wc>=19){
7876                 /* primary request */
7877                 sc = tvb_get_guint8(tvb, offset);
7878                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
7879                 offset += 1;
7880         } else {
7881                 /* secondary request */
7882                 sc = 0;
7883         }
7884
7885         /* function */
7886         if(wc>=19){
7887                 /* primary request */
7888                 subcmd = tvb_get_letohs(tvb, offset);
7889                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
7890                 if(check_col(pinfo->cinfo, COL_INFO)){
7891                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
7892                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
7893                 }
7894                 ntd.subcmd = subcmd;
7895                 if (!si->unidir) {
7896                         if(!pinfo->fd->flags.visited){
7897                                 /*
7898                                  * Allocate a new smb_nt_transact_info_t
7899                                  * structure.
7900                                  */
7901                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
7902                                 nti->subcmd = subcmd;
7903                                 sip->extra_info = nti;
7904                         }
7905                 }
7906         } else {
7907                 /* secondary request */
7908                 if(check_col(pinfo->cinfo, COL_INFO)){
7909                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
7910                 }
7911         }
7912         offset += 2;
7913
7914         /* this is a padding byte */
7915         if(offset%1){
7916                 /* pad byte */
7917                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
7918                 offset += 1;
7919         }
7920
7921         /* if there were any setup bytes, decode them */
7922         if(sc){
7923                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
7924                 offset += sc*2;
7925         }
7926
7927         BYTE_COUNT;
7928
7929         /* parameters */
7930         if(po>(guint32)offset){
7931                 /* We have some initial padding bytes.
7932                 */
7933                 padcnt = po-offset;
7934                 if (padcnt > bc)
7935                         padcnt = bc;
7936                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7937                 COUNT_BYTES(padcnt);
7938         }
7939         if(pc){
7940                 CHECK_BYTE_COUNT(pc);
7941                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
7942                 COUNT_BYTES(pc);
7943         }
7944
7945         /* data */
7946         if(od>(guint32)offset){
7947                 /* We have some initial padding bytes.
7948                 */
7949                 padcnt = od-offset;
7950                 if (padcnt > bc)
7951                         padcnt = bc;
7952                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7953                 COUNT_BYTES(padcnt);
7954         }
7955         if(dc){
7956                 CHECK_BYTE_COUNT(dc);
7957                 dissect_nt_trans_data_request(tvb, pinfo, offset, tree, dc, &ntd);
7958                 COUNT_BYTES(dc);
7959         }
7960
7961         END_OF_SMB
7962
7963         return offset;
7964 }
7965
7966
7967
7968 static int
7969 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
7970                                int offset, proto_tree *parent_tree, int len,
7971                                nt_trans_data *ntd _U_)
7972 {
7973         proto_item *item = NULL;
7974         proto_tree *tree = NULL;
7975         smb_info_t *si;
7976         smb_nt_transact_info_t *nti;
7977         guint16 bcp;
7978
7979         si = (smb_info_t *)pinfo->private_data;
7980         if (si->sip != NULL)
7981                 nti = si->sip->extra_info;
7982         else
7983                 nti = NULL;
7984
7985         if(parent_tree){
7986                 if(nti != NULL){
7987                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7988                                 "%s Data",
7989                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7990                 } else {
7991                         /*
7992                          * We never saw the request to which this is a
7993                          * response.
7994                          */
7995                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7996                                 "Unknown NT Transaction Data (matching request not seen)");
7997                 }
7998                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7999         }
8000
8001         if (nti == NULL) {
8002                 offset += len;
8003                 return offset;
8004         }
8005         switch(nti->subcmd){
8006         case NT_TRANS_CREATE:
8007                 break;
8008         case NT_TRANS_IOCTL:
8009                 /* ioctl data */
8010                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
8011                 offset += len;
8012
8013                 break;
8014         case NT_TRANS_SSD:
8015                 break;
8016         case NT_TRANS_NOTIFY:
8017                 break;
8018         case NT_TRANS_RENAME:
8019                 /* XXX not documented */
8020                 break;
8021         case NT_TRANS_QSD:
8022                 /*
8023                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
8024                  * which may be documented in the Win32 documentation
8025                  * somewhere.
8026                  */
8027                 offset = dissect_nt_sec_desc(tvb, offset, tree, len);
8028                 break;
8029         case NT_TRANS_GET_USER_QUOTA:
8030                 bcp=len;
8031                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8032                 break;
8033         case NT_TRANS_SET_USER_QUOTA:
8034                 /* not decoded yet */
8035                 break;
8036         }
8037
8038         return offset;
8039 }
8040
8041 static int
8042 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
8043                                 int offset, proto_tree *parent_tree,
8044                                 int len, nt_trans_data *ntd _U_, guint16 bc)
8045 {
8046         proto_item *item = NULL;
8047         proto_tree *tree = NULL;
8048         guint32 fn_len;
8049         const char *fn;
8050         smb_info_t *si;
8051         smb_nt_transact_info_t *nti;
8052         guint16 fid;
8053         int old_offset;
8054         guint32 neo;
8055         int padcnt;
8056
8057         si = (smb_info_t *)pinfo->private_data;
8058         if (si->sip != NULL)
8059                 nti = si->sip->extra_info;
8060         else
8061                 nti = NULL;
8062
8063         if(parent_tree){
8064                 if(nti != NULL){
8065                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8066                                 "%s Parameters",
8067                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8068                 } else {
8069                         /*
8070                          * We never saw the request to which this is a
8071                          * response.
8072                          */
8073                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8074                                 "Unknown NT Transaction Parameters (matching request not seen)");
8075                 }
8076                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8077         }
8078
8079         if (nti == NULL) {
8080                 offset += len;
8081                 return offset;
8082         }
8083         switch(nti->subcmd){
8084         case NT_TRANS_CREATE:
8085                 /* oplock level */
8086                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8087                 offset += 1;
8088
8089                 /* reserved byte */
8090                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8091                 offset += 1;
8092
8093                 /* fid */
8094                 fid = tvb_get_letohs(tvb, offset);
8095                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8096                 offset += 2;
8097
8098                 /* create action */
8099                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8100                 offset += 4;
8101
8102                 /* ea error offset */
8103                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
8104                 offset += 4;
8105
8106                 /* create time */
8107                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8108                         hf_smb_create_time);
8109
8110                 /* access time */
8111                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8112                         hf_smb_access_time);
8113
8114                 /* last write time */
8115                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8116                         hf_smb_last_write_time);
8117
8118                 /* last change time */
8119                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8120                         hf_smb_change_time);
8121
8122                 /* Extended File Attributes */
8123                 offset = dissect_file_ext_attr(tvb, tree, offset);
8124
8125                 /* allocation size */
8126                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8127                 offset += 8;
8128
8129                 /* end of file */
8130                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8131                 offset += 8;
8132
8133                 /* File Type */
8134                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8135                 offset += 2;
8136
8137                 /* device state */
8138                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8139
8140                 /* is directory */
8141                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8142                 offset += 1;
8143                 break;
8144         case NT_TRANS_IOCTL:
8145                 break;
8146         case NT_TRANS_SSD:
8147                 break;
8148         case NT_TRANS_NOTIFY:
8149                 while(len){
8150                         old_offset = offset;
8151
8152                         /* next entry offset */
8153                         neo = tvb_get_letohl(tvb, offset);
8154                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8155                         COUNT_BYTES(4);
8156                         len -= 4;
8157                         /* broken implementations */
8158                         if(len<0)break;
8159
8160                         /* action */
8161                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
8162                         COUNT_BYTES(4);
8163                         len -= 4;
8164                         /* broken implementations */
8165                         if(len<0)break;
8166
8167                         /* file name len */
8168                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
8169                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8170                         COUNT_BYTES(4);
8171                         len -= 4;
8172                         /* broken implementations */
8173                         if(len<0)break;
8174
8175                         /* file name */
8176                         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8177                         if (fn == NULL)
8178                                 break;
8179                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8180                                 fn);
8181                         COUNT_BYTES(fn_len);
8182                         len -= fn_len;
8183                         /* broken implementations */
8184                         if(len<0)break;
8185
8186                         if (neo == 0)
8187                                 break;  /* no more structures */
8188
8189                         /* skip to next structure */
8190                         padcnt = (old_offset + neo) - offset;
8191                         if (padcnt < 0) {
8192                                 /*
8193                                  * XXX - this is bogus; flag it?
8194                                  */
8195                                 padcnt = 0;
8196                         }
8197                         if (padcnt != 0) {
8198                                 COUNT_BYTES(padcnt);
8199                                 len -= padcnt;
8200                                 /* broken implementations */
8201                                 if(len<0)break;
8202                         }
8203                 }
8204                 break;
8205         case NT_TRANS_RENAME:
8206                 /* XXX not documented */
8207                 break;
8208         case NT_TRANS_QSD:
8209                 /*
8210                  * This appears to be the size of the security
8211                  * descriptor; the calling sequence of
8212                  * "ZwQuerySecurityObject()" suggests that it would
8213                  * be.  The actual security descriptor wouldn't
8214                  * follow if the max data count in the request
8215                  * was smaller; this lets the client know how
8216                  * big a buffer it needs to provide.
8217                  */
8218                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
8219                 offset += 4;
8220                 break;
8221         case NT_TRANS_GET_USER_QUOTA:
8222                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
8223                         tvb_get_letohl(tvb, offset));
8224                 offset += 4;
8225                 break;
8226         case NT_TRANS_SET_USER_QUOTA:
8227                 /* not decoded yet */
8228                 break;
8229         }
8230
8231         return offset;
8232 }
8233
8234 static int
8235 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
8236                                 int offset, proto_tree *parent_tree,
8237                                 int len, nt_trans_data *ntd _U_)
8238 {
8239         proto_item *item = NULL;
8240         proto_tree *tree = NULL;
8241         smb_info_t *si;
8242         smb_nt_transact_info_t *nti;
8243
8244         si = (smb_info_t *)pinfo->private_data;
8245         if (si->sip != NULL)
8246                 nti = si->sip->extra_info;
8247         else
8248                 nti = NULL;
8249
8250         if(parent_tree){
8251                 if(nti != NULL){
8252                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8253                                 "%s Setup",
8254                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8255                 } else {
8256                         /*
8257                          * We never saw the request to which this is a
8258                          * response.
8259                          */
8260                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8261                                 "Unknown NT Transaction Setup (matching request not seen)");
8262                 }
8263                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8264         }
8265
8266         if (nti == NULL) {
8267                 offset += len;
8268                 return offset;
8269         }
8270         switch(nti->subcmd){
8271         case NT_TRANS_CREATE:
8272                 break;
8273         case NT_TRANS_IOCTL:
8274                 break;
8275         case NT_TRANS_SSD:
8276                 break;
8277         case NT_TRANS_NOTIFY:
8278                 break;
8279         case NT_TRANS_RENAME:
8280                 /* XXX not documented */
8281                 break;
8282         case NT_TRANS_QSD:
8283                 break;
8284         case NT_TRANS_GET_USER_QUOTA:
8285                 /* not decoded yet */
8286                 break;
8287         case NT_TRANS_SET_USER_QUOTA:
8288                 /* not decoded yet */
8289                 break;
8290         }
8291
8292         return offset;
8293 }
8294
8295 static int
8296 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8297 {
8298         guint8 wc, sc;
8299         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
8300         guint32 td=0, tp=0;
8301         smb_info_t *si;
8302         smb_nt_transact_info_t *nti;
8303         static nt_trans_data ntd;
8304         guint16 bc;
8305         int padcnt;
8306         fragment_data *r_fd = NULL;
8307         tvbuff_t *pd_tvb=NULL;
8308         gboolean save_fragmented;
8309
8310         si = (smb_info_t *)pinfo->private_data;
8311         if (si->sip != NULL)
8312                 nti = si->sip->extra_info;
8313         else
8314                 nti = NULL;
8315
8316         /* primary request */
8317         if(nti != NULL){
8318                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
8319                 if(check_col(pinfo->cinfo, COL_INFO)){
8320                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8321                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
8322                 }
8323         } else {
8324                 proto_tree_add_text(tree, tvb, offset, 0,
8325                         "Function: <unknown function - could not find matching request>");
8326                 if(check_col(pinfo->cinfo, COL_INFO)){
8327                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
8328                 }
8329         }
8330
8331         WORD_COUNT;
8332
8333         /* 3 reserved bytes */
8334         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8335         offset += 3;
8336
8337         /* total param count */
8338         tp = tvb_get_letohl(tvb, offset);
8339         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8340         offset += 4;
8341
8342         /* total data count */
8343         td = tvb_get_letohl(tvb, offset);
8344         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8345         offset += 4;
8346
8347         /* param count */
8348         pc = tvb_get_letohl(tvb, offset);
8349         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8350         offset += 4;
8351
8352         /* param offset */
8353         po = tvb_get_letohl(tvb, offset);
8354         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8355         offset += 4;
8356
8357         /* param displacement */
8358         pd = tvb_get_letohl(tvb, offset);
8359         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8360         offset += 4;
8361
8362         /* data count */
8363         dc = tvb_get_letohl(tvb, offset);
8364         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8365         offset += 4;
8366
8367         /* data offset */
8368         od = tvb_get_letohl(tvb, offset);
8369         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8370         offset += 4;
8371
8372         /* data displacement */
8373         dd = tvb_get_letohl(tvb, offset);
8374         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8375         offset += 4;
8376
8377         /* setup count */
8378         sc = tvb_get_guint8(tvb, offset);
8379         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8380         offset += 1;
8381
8382         /* setup data */
8383         if(sc){
8384                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
8385                 offset += sc*2;
8386         }
8387
8388         BYTE_COUNT;
8389
8390         /* reassembly of SMB NT Transaction data payload.
8391            In this section we do reassembly of both the data and parameters
8392            blocks of the SMB transaction command.
8393         */
8394         save_fragmented = pinfo->fragmented;
8395         /* do we need reassembly? */
8396         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
8397                 /* oh yeah, either data or parameter section needs
8398                    reassembly...
8399                 */
8400                 pinfo->fragmented = TRUE;
8401                 if(smb_trans_reassembly){
8402                         /* ...and we were told to do reassembly */
8403                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
8404                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8405                                                              po, pc, pd, td+tp);
8406
8407                         }
8408                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
8409                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8410                                                              od, dc, dd+tp, td+tp);
8411                         }
8412                 }
8413         }
8414
8415         /* if we got a reassembled fd structure from the reassembly routine we
8416            must create pd_tvb from it
8417         */
8418         if(r_fd){
8419                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
8420                                              r_fd->datalen);
8421                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
8422                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
8423
8424                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
8425         }
8426
8427
8428         if(pd_tvb){
8429           /* we have reassembled data, grab param and data from there */
8430           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
8431                                           &ntd, tvb_length(pd_tvb));
8432           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
8433         } else {
8434           /* we do not have reassembled data, just use what we have in the
8435              packet as well as we can */
8436           /* parameters */
8437           if(po>(guint32)offset){
8438             /* We have some initial padding bytes.
8439              */
8440             padcnt = po-offset;
8441             if (padcnt > bc)
8442               padcnt = bc;
8443             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8444             COUNT_BYTES(padcnt);
8445           }
8446           if(pc){
8447             CHECK_BYTE_COUNT(pc);
8448             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
8449             COUNT_BYTES(pc);
8450           }
8451
8452           /* data */
8453           if(od>(guint32)offset){
8454             /* We have some initial padding bytes.
8455              */
8456             padcnt = od-offset;
8457             if (padcnt > bc)
8458               padcnt = bc;
8459             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8460             COUNT_BYTES(padcnt);
8461           }
8462           if(dc){
8463             CHECK_BYTE_COUNT(dc);
8464             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
8465             COUNT_BYTES(dc);
8466           }
8467         }
8468         pinfo->fragmented = save_fragmented;
8469
8470         END_OF_SMB
8471
8472         return offset;
8473 }
8474
8475 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8476    NT Transaction command  ends here
8477    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8478
8479 static const value_string print_mode_vals[] = {
8480         {0,     "Text Mode"},
8481         {1,     "Graphics Mode"},
8482         {0, NULL}
8483 };
8484
8485 static int
8486 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8487 {
8488         smb_info_t *si = pinfo->private_data;
8489         int fn_len;
8490         const char *fn;
8491         guint8 wc;
8492         guint16 bc;
8493
8494         WORD_COUNT;
8495
8496         /* setup len */
8497         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
8498         offset += 2;
8499
8500         /* print mode */
8501         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
8502         offset += 2;
8503
8504         BYTE_COUNT;
8505
8506         /* buffer format */
8507         CHECK_BYTE_COUNT(1);
8508         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8509         COUNT_BYTES(1);
8510
8511         /* print identifier */
8512         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
8513         if (fn == NULL)
8514                 goto endofcommand;
8515         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
8516                 fn);
8517         COUNT_BYTES(fn_len);
8518
8519         END_OF_SMB
8520
8521         return offset;
8522 }
8523
8524
8525 static int
8526 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8527 {
8528         int cnt;
8529         guint8 wc;
8530         guint16 bc, fid;
8531
8532         WORD_COUNT;
8533
8534         /* fid */
8535         fid = tvb_get_letohs(tvb, offset);
8536         add_fid(tvb, pinfo, tree, offset, 2, fid);
8537         offset += 2;
8538
8539         BYTE_COUNT;
8540
8541         /* buffer format */
8542         CHECK_BYTE_COUNT(1);
8543         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8544         COUNT_BYTES(1);
8545
8546         /* data len */
8547         CHECK_BYTE_COUNT(2);
8548         cnt = tvb_get_letohs(tvb, offset);
8549         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
8550         COUNT_BYTES(2);
8551
8552         /* file data */
8553         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
8554
8555         END_OF_SMB
8556
8557         return offset;
8558 }
8559
8560
8561 static const value_string print_status_vals[] = {
8562         {1,     "Held or Stopped"},
8563         {2,     "Printing"},
8564         {3,     "Awaiting print"},
8565         {4,     "In intercept"},
8566         {5,     "File had error"},
8567         {6,     "Printer error"},
8568         {0, NULL}
8569 };
8570
8571 static int
8572 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8573 {
8574         guint8 wc;
8575         guint16 bc;
8576
8577         WORD_COUNT;
8578
8579         /* max count */
8580         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
8581         offset += 2;
8582
8583         /* start index */
8584         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
8585         offset += 2;
8586
8587         BYTE_COUNT;
8588
8589         END_OF_SMB
8590
8591         return offset;
8592 }
8593
8594 static int
8595 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
8596     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
8597 {
8598         proto_item *item = NULL;
8599         proto_tree *tree = NULL;
8600         smb_info_t *si = pinfo->private_data;
8601         int fn_len;
8602         const char *fn;
8603
8604         if(parent_tree){
8605                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
8606                         "Queue entry");
8607                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
8608         }
8609
8610         /* queued time */
8611         CHECK_BYTE_COUNT_SUBR(4);
8612         offset = dissect_smb_datetime(tvb, tree, offset,
8613                 hf_smb_print_queue_date,
8614                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
8615         *bcp -= 4;
8616
8617         /* status */
8618         CHECK_BYTE_COUNT_SUBR(1);
8619         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
8620         COUNT_BYTES_SUBR(1);
8621
8622         /* spool file number */
8623         CHECK_BYTE_COUNT_SUBR(2);
8624         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
8625         COUNT_BYTES_SUBR(2);
8626
8627         /* spool file size */
8628         CHECK_BYTE_COUNT_SUBR(4);
8629         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
8630         COUNT_BYTES_SUBR(4);
8631
8632         /* reserved byte */
8633         CHECK_BYTE_COUNT_SUBR(1);
8634         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8635         COUNT_BYTES_SUBR(1);
8636
8637         /* file name */
8638         fn_len = 16;
8639         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
8640         CHECK_STRING_SUBR(fn);
8641         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
8642                 fn);
8643         COUNT_BYTES_SUBR(fn_len);
8644
8645         *trunc = FALSE;
8646         return offset;
8647 }
8648
8649 static int
8650 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8651 {
8652         guint16 cnt=0, len;
8653         guint8 wc;
8654         guint16 bc;
8655         gboolean trunc;
8656
8657         WORD_COUNT;
8658
8659         /* count */
8660         cnt = tvb_get_letohs(tvb, offset);
8661         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
8662         offset += 2;
8663
8664         /* restart index */
8665         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
8666         offset += 2;
8667
8668         BYTE_COUNT;
8669
8670         /* buffer format */
8671         CHECK_BYTE_COUNT(1);
8672         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8673         COUNT_BYTES(1);
8674
8675         /* data len */
8676         CHECK_BYTE_COUNT(2);
8677         len = tvb_get_letohs(tvb, offset);
8678         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
8679         COUNT_BYTES(2);
8680
8681         /* queue elements */
8682         while(cnt--){
8683                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
8684                     &bc, &trunc);
8685                 if (trunc)
8686                         goto endofcommand;
8687         }
8688
8689         END_OF_SMB
8690
8691         return offset;
8692 }
8693
8694
8695 static int
8696 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8697 {
8698         int name_len;
8699         guint16 bc;
8700         guint8 wc;
8701         guint16 message_len;
8702
8703         WORD_COUNT;
8704
8705         BYTE_COUNT;
8706
8707         /* buffer format */
8708         CHECK_BYTE_COUNT(1);
8709         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8710         COUNT_BYTES(1);
8711
8712         /* originator name */
8713         /* XXX - what if this runs past bc? */
8714         name_len = tvb_strsize(tvb, offset);
8715         CHECK_BYTE_COUNT(name_len);
8716         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
8717             name_len, TRUE);
8718         COUNT_BYTES(name_len);
8719
8720         /* buffer format */
8721         CHECK_BYTE_COUNT(1);
8722         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8723         COUNT_BYTES(1);
8724
8725         /* destination name */
8726         /* XXX - what if this runs past bc? */
8727         name_len = tvb_strsize(tvb, offset);
8728         CHECK_BYTE_COUNT(name_len);
8729         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
8730             name_len, TRUE);
8731         COUNT_BYTES(name_len);
8732
8733         /* buffer format */
8734         CHECK_BYTE_COUNT(1);
8735         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8736         COUNT_BYTES(1);
8737
8738         /* message len */
8739         CHECK_BYTE_COUNT(2);
8740         message_len = tvb_get_letohs(tvb, offset);
8741         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
8742             message_len);
8743         COUNT_BYTES(2);
8744
8745         /* message */
8746         CHECK_BYTE_COUNT(message_len);
8747         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
8748             TRUE);
8749         COUNT_BYTES(message_len);
8750
8751         END_OF_SMB
8752
8753         return offset;
8754 }
8755
8756 static int
8757 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8758 {
8759         int name_len;
8760         guint16 bc;
8761         guint8 wc;
8762
8763         WORD_COUNT;
8764
8765         BYTE_COUNT;
8766
8767         /* buffer format */
8768         CHECK_BYTE_COUNT(1);
8769         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8770         COUNT_BYTES(1);
8771
8772         /* originator name */
8773         /* XXX - what if this runs past bc? */
8774         name_len = tvb_strsize(tvb, offset);
8775         CHECK_BYTE_COUNT(name_len);
8776         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
8777             name_len, TRUE);
8778         COUNT_BYTES(name_len);
8779
8780         /* buffer format */
8781         CHECK_BYTE_COUNT(1);
8782         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8783         COUNT_BYTES(1);
8784
8785         /* destination name */
8786         /* XXX - what if this runs past bc? */
8787         name_len = tvb_strsize(tvb, offset);
8788         CHECK_BYTE_COUNT(name_len);
8789         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
8790             name_len, TRUE);
8791         COUNT_BYTES(name_len);
8792
8793         END_OF_SMB
8794
8795         return offset;
8796 }
8797
8798 static int
8799 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8800 {
8801         guint16 bc;
8802         guint8 wc;
8803
8804         WORD_COUNT;
8805
8806         /* message group ID */
8807         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
8808         offset += 2;
8809
8810         BYTE_COUNT;
8811
8812         END_OF_SMB
8813
8814         return offset;
8815 }
8816
8817 static int
8818 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8819 {
8820         guint16 bc;
8821         guint8 wc;
8822         guint16 message_len;
8823
8824         WORD_COUNT;
8825
8826         BYTE_COUNT;
8827
8828         /* buffer format */
8829         CHECK_BYTE_COUNT(1);
8830         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8831         COUNT_BYTES(1);
8832
8833         /* message len */
8834         CHECK_BYTE_COUNT(2);
8835         message_len = tvb_get_letohs(tvb, offset);
8836         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
8837             message_len);
8838         COUNT_BYTES(2);
8839
8840         /* message */
8841         CHECK_BYTE_COUNT(message_len);
8842         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
8843             TRUE);
8844         COUNT_BYTES(message_len);
8845
8846         END_OF_SMB
8847
8848         return offset;
8849 }
8850
8851 static int
8852 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8853 {
8854         int name_len;
8855         guint16 bc;
8856         guint8 wc;
8857
8858         WORD_COUNT;
8859
8860         BYTE_COUNT;
8861
8862         /* buffer format */
8863         CHECK_BYTE_COUNT(1);
8864         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8865         COUNT_BYTES(1);
8866
8867         /* forwarded name */
8868         /* XXX - what if this runs past bc? */
8869         name_len = tvb_strsize(tvb, offset);
8870         CHECK_BYTE_COUNT(name_len);
8871         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
8872             name_len, TRUE);
8873         COUNT_BYTES(name_len);
8874
8875         END_OF_SMB
8876
8877         return offset;
8878 }
8879
8880 static int
8881 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8882 {
8883         int name_len;
8884         guint16 bc;
8885         guint8 wc;
8886
8887         WORD_COUNT;
8888
8889         BYTE_COUNT;
8890
8891         /* buffer format */
8892         CHECK_BYTE_COUNT(1);
8893         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8894         COUNT_BYTES(1);
8895
8896         /* machine name */
8897         /* XXX - what if this runs past bc? */
8898         name_len = tvb_strsize(tvb, offset);
8899         CHECK_BYTE_COUNT(name_len);
8900         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
8901             name_len, TRUE);
8902         COUNT_BYTES(name_len);
8903
8904         END_OF_SMB
8905
8906         return offset;
8907 }
8908
8909
8910 static int
8911 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8912 {
8913         guint8  wc, cmd=0xff;
8914         guint16 andxoffset=0;
8915         guint16 bc;
8916         smb_info_t *si = pinfo->private_data;
8917         int fn_len;
8918         const char *fn;
8919
8920         WORD_COUNT;
8921
8922         /* next smb command */
8923         cmd = tvb_get_guint8(tvb, offset);
8924         if(cmd!=0xff){
8925                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
8926         } else {
8927                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
8928         }
8929         offset += 1;
8930
8931         /* reserved byte */
8932         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8933         offset += 1;
8934
8935         /* andxoffset */
8936         andxoffset = tvb_get_letohs(tvb, offset);
8937         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8938         offset += 2;
8939
8940         /* reserved byte */
8941         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8942         offset += 1;
8943
8944         /* file name len */
8945         fn_len = tvb_get_letohs(tvb, offset);
8946         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
8947         offset += 2;
8948
8949         /* Create flags */
8950         offset = dissect_nt_create_bits(tvb, tree, offset);
8951
8952         /* root directory fid */
8953         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
8954         offset += 4;
8955
8956         /* nt access mask */
8957         offset = dissect_nt_access_mask(tvb, tree, offset);
8958
8959         /* allocation size */
8960         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8961         offset += 8;
8962
8963         /* Extended File Attributes */
8964         offset = dissect_file_ext_attr(tvb, tree, offset);
8965
8966         /* share access */
8967         offset = dissect_nt_share_access(tvb, tree, offset);
8968
8969         /* create disposition */
8970         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8971         offset += 4;
8972
8973         /* create options */
8974         offset = dissect_nt_create_options(tvb, tree, offset);
8975
8976         /* impersonation level */
8977         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8978         offset += 4;
8979
8980         /* security flags */
8981         offset = dissect_nt_security_flags(tvb, tree, offset);
8982
8983         BYTE_COUNT;
8984
8985         /* file name */
8986         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
8987         if (fn == NULL)
8988                 goto endofcommand;
8989         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8990                 fn);
8991         COUNT_BYTES(fn_len);
8992
8993         if (check_col(pinfo->cinfo, COL_INFO)) {
8994                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
8995         }
8996
8997         END_OF_SMB
8998
8999         /* call AndXCommand (if there are any) */
9000         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9001
9002         return offset;
9003 }
9004
9005
9006 static int
9007 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9008 {
9009         guint8  wc, cmd=0xff;
9010         guint16 andxoffset=0;
9011         guint16 bc;
9012         guint16 fid;
9013
9014         WORD_COUNT;
9015
9016         /* next smb command */
9017         cmd = tvb_get_guint8(tvb, offset);
9018         if(cmd!=0xff){
9019                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9020         } else {
9021                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
9022         }
9023         offset += 1;
9024
9025         /* reserved byte */
9026         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9027         offset += 1;
9028
9029         /* andxoffset */
9030         andxoffset = tvb_get_letohs(tvb, offset);
9031         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9032         offset += 2;
9033
9034         /* oplock level */
9035         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
9036         offset += 1;
9037
9038         /* fid */
9039         fid = tvb_get_letohs(tvb, offset);
9040         add_fid(tvb, pinfo, tree, offset, 2, fid);
9041         offset += 2;
9042
9043         /* create action */
9044         /*XXX is this really the same as create disposition in the request? it looks so*/
9045         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
9046         offset += 4;
9047
9048         /* create time */
9049         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
9050
9051         /* access time */
9052         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
9053
9054         /* last write time */
9055         offset = dissect_smb_64bit_time(tvb, tree, offset,
9056                 hf_smb_last_write_time);
9057
9058         /* last change time */
9059         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
9060
9061         /* Extended File Attributes */
9062         offset = dissect_file_ext_attr(tvb, tree, offset);
9063
9064         /* allocation size */
9065         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9066         offset += 8;
9067
9068         /* end of file */
9069         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9070         offset += 8;
9071
9072         /* File Type */
9073         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
9074         offset += 2;
9075
9076         /* IPC State */
9077         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9078
9079         /* is directory */
9080         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9081         offset += 1;
9082
9083         BYTE_COUNT;
9084
9085         END_OF_SMB
9086
9087         /* call AndXCommand (if there are any) */
9088         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9089
9090         return offset;
9091 }
9092
9093
9094 static int
9095 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9096 {
9097         guint8 wc;
9098         guint16 bc;
9099
9100         WORD_COUNT;
9101
9102         BYTE_COUNT;
9103
9104         END_OF_SMB
9105
9106         return offset;
9107 }
9108
9109 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9110    BEGIN Transaction/Transaction2 Primary and secondary requests
9111    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9112
9113
9114 static const value_string trans2_cmd_vals[] = {
9115         { 0x00,         "OPEN2" },
9116         { 0x01,         "FIND_FIRST2" },
9117         { 0x02,         "FIND_NEXT2" },
9118         { 0x03,         "QUERY_FS_INFORMATION" },
9119         { 0x04,         "SET_FS_QUOTA" },
9120         { 0x05,         "QUERY_PATH_INFORMATION" },
9121         { 0x06,         "SET_PATH_INFORMATION" },
9122         { 0x07,         "QUERY_FILE_INFORMATION" },
9123         { 0x08,         "SET_FILE_INFORMATION" },
9124         { 0x09,         "FSCTL" },
9125         { 0x0A,         "IOCTL2" },
9126         { 0x0B,         "FIND_NOTIFY_FIRST" },
9127         { 0x0C,         "FIND_NOTIFY_NEXT" },
9128         { 0x0D,         "CREATE_DIRECTORY" },
9129         { 0x0E,         "SESSION_SETUP" },
9130         { 0x10,         "GET_DFS_REFERRAL" },
9131         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
9132         { 0,    NULL }
9133 };
9134
9135 static const true_false_string tfs_tf_dtid = {
9136         "Also DISCONNECT TID",
9137         "Do NOT disconnect TID"
9138 };
9139 static const true_false_string tfs_tf_owt = {
9140         "One Way Transaction (NO RESPONSE)",
9141         "Two way transaction"
9142 };
9143
9144 static const true_false_string tfs_ff2_backup = {
9145         "Find WITH backup intent",
9146         "No backup intent"
9147 };
9148 static const true_false_string tfs_ff2_continue = {
9149         "CONTINUE search from previous position",
9150         "New search, do NOT continue from previous position"
9151 };
9152 static const true_false_string tfs_ff2_resume = {
9153         "Return RESUME keys",
9154         "Do NOT return resume keys"
9155 };
9156 static const true_false_string tfs_ff2_close_eos = {
9157         "CLOSE search if END OF SEARCH is reached",
9158         "Do NOT close search if end of search reached"
9159 };
9160 static const true_false_string tfs_ff2_close = {
9161         "CLOSE search after this request",
9162         "Do NOT close search after this request"
9163 };
9164
9165 /* used by
9166    TRANS2_FIND_FIRST2
9167 */
9168 static const value_string ff2_il_vals[] = {
9169         { 1,            "Info Standard  (4.3.4.1)"},
9170         { 2,            "Info Query EA Size  (4.3.4.2)"},
9171         { 3,            "Info Query EAs From List  (4.3.4.2)"},
9172         { 0x0101,       "Find File Directory Info  (4.3.4.4)"},
9173         { 0x0102,       "Find File Full Directory Info  (4.3.4.5)"},
9174         { 0x0103,       "Find File Names Info  (4.3.4.7)"},
9175         { 0x0104,       "Find File Both Directory Info  (4.3.4.6)"},
9176         { 0x0202,       "Find File UNIX  (4.3.4.8)"},
9177         {0, NULL}
9178 };
9179
9180 /* values used by :
9181         TRANS2_QUERY_PATH_INFORMATION
9182         TRANS2_SET_PATH_INFORMATION
9183 */
9184 static const value_string qpi_loi_vals[] = {
9185         { 1,            "Info Standard  (4.2.14.1)"},
9186         { 2,            "Info Query EA Size  (4.2.14.1)"},
9187         { 3,            "Info Query EAs From List  (4.2.14.2)"},
9188         { 4,            "Info Query All EAs  (4.2.14.2)"},
9189         { 6,            "Info Is Name Valid  (4.2.14.3)"},
9190         { 0x0101,       "Query File Basic Info  (4.2.14.4)"},
9191         { 0x0102,       "Query File Standard Info  (4.2.14.5)"},
9192         { 0x0103,       "Query File EA Info  (4.2.14.6)"},
9193         { 0x0104,       "Query File Name Info  (4.2.14.7)"},
9194         { 0x0107,       "Query File All Info  (4.2.14.8)"},
9195         { 0x0108,       "Query File Alt Name Info  (4.2.14.7)"},
9196         { 0x0109,       "Query File Stream Info  (4.2.14.10)"},
9197         { 0x010b,       "Query File Compression Info  (4.2.14.11)"},
9198         { 0x0200,       "Set File Unix Basic"},
9199         { 0x0201,       "Set File Unix Link"},
9200         { 0x0202,       "Set File Unix HardLink"},
9201         { 1004,         "Query File Basic Info  (4.2.14.4)"},
9202         { 1005,         "Query File Standard Info  (4.2.14.5)"},
9203         { 1006,         "Query File Internal Info  (4.2.14.?)"},
9204         { 1007,         "Query File EA Info  (4.2.14.6)"},
9205         { 1009,         "Query File Name Info  (4.2.14.7)"},
9206         { 1010,         "Query File Rename Info  (4.2.14.?)"},
9207         { 1011,         "Query File Link Info  (4.2.14.?)"},
9208         { 1012,         "Query File Names Info  (4.2.14.?)"},
9209         { 1013,         "Query File Disposition Info  (4.2.14.?)"},
9210         { 1014,         "Query File Position Info  (4.2.14.?)"},
9211         { 1015,         "Query File Full EA Info  (4.2.14.?)"},
9212         { 1016,         "Query File Mode Info  (4.2.14.?)"},
9213         { 1017,         "Query File Alignment Info  (4.2.14.?)"},
9214         { 1018,         "Query File All Info  (4.2.14.8)"},
9215         { 1019,         "Query File Allocation Info  (4.2.14.?)"},
9216         { 1020,         "Query File End of File Info  (4.2.14.?)"},
9217         { 1021,         "Query File Alt Name Info  (4.2.14.7)"},
9218         { 1022,         "Query File Stream Info  (4.2.14.10)"},
9219         { 1023,         "Query File Pipe Info  (4.2.14.?)"},
9220         { 1024,         "Query File Pipe Local Info  (4.2.14.?)"},
9221         { 1025,         "Query File Pipe Remote Info  (4.2.14.?)"},
9222         { 1026,         "Query File Mailslot Query Info  (4.2.14.?)"},
9223         { 1027,         "Query File Mailslot Set Info  (4.2.14.?)"},
9224         { 1028,         "Query File Compression Info  (4.2.14.11)"},
9225         { 1029,         "Query File ObjectID Info  (4.2.14.?)"},
9226         { 1030,         "Query File Completion Info  (4.2.14.?)"},
9227         { 1031,         "Query File Move Cluster Info  (4.2.14.?)"},
9228         { 1032,         "Query File Quota Info  (4.2.14.?)"},
9229         { 1033,         "Query File Reparsepoint Info  (4.2.14.?)"},
9230         { 1034,         "Query File Network Open Info  (4.2.14.?)"},
9231         { 1035,         "Query File Attribute Tag Info  (4.2.14.?)"},
9232         { 1036,         "Query File Tracking Info  (4.2.14.?)"},
9233         { 1037,         "Query File Maximum Info  (4.2.14.?)"},
9234         {0, NULL}
9235 };
9236
9237 static const value_string qfsi_vals[] = {
9238         { 1,            "Info Allocation"},
9239         { 2,            "Info Volume"},
9240         { 0x0101,       "Query FS Label Info"},
9241         { 0x0102,       "Query FS Volume Info"},
9242         { 0x0103,       "Query FS Size Info"},
9243         { 0x0104,       "Query FS Device Info"},
9244         { 0x0105,       "Query FS Attribute Info"},
9245         { 0x0301,       "Mac Query FS INFO"},
9246         { 1001,         "Query FS Label Info"},
9247         { 1002,         "Query FS Volume Info"},
9248         { 1003,         "Query FS Size Info"},
9249         { 1004,         "Query FS Device Info"},
9250         { 1005,         "Query FS Attribute Info"},
9251         { 1006,         "Query FS Quota Info"},
9252         { 1007,         "Query Full FS Size Info"},
9253         {0, NULL}
9254 };
9255
9256 static const value_string nt_rename_vals[] = {
9257         { 0x0103,       "Create Hard Link"},
9258         {0, NULL}
9259 };
9260
9261
9262 static const value_string delete_pending_vals[] = {
9263         {0,     "Normal, no pending delete"},
9264         {1,     "This object has DELETE PENDING"},
9265         {0, NULL}
9266 };
9267
9268 static const value_string alignment_vals[] = {
9269         {0,     "Byte alignment"},
9270         {1,     "Word (16bit) alignment"},
9271         {3,     "Long (32bit) alignment"},
9272         {7,     "8 byte boundary alignment"},
9273         {0x0f,  "16 byte boundary alignment"},
9274         {0x1f,  "32 byte boundary alignment"},
9275         {0x3f,  "64 byte boundary alignment"},
9276         {0x7f,  "128 byte boundary alignment"},
9277         {0xff,  "256 byte boundary alignment"},
9278         {0x1ff, "512 byte boundary alignment"},
9279         {0, NULL}
9280 };
9281
9282
9283 static const true_false_string tfs_get_dfs_server_hold_storage = {
9284         "Referral SERVER HOLDS STORAGE for the file",
9285         "Referral server does NOT hold storage for the file"
9286 };
9287 static const true_false_string tfs_get_dfs_fielding = {
9288         "The server in referral is FIELDING CAPABLE",
9289         "The server in referrals is NOT fielding capable"
9290 };
9291
9292 static const true_false_string tfs_dfs_referral_flags_strip = {
9293         "STRIP off pathconsumed characters before submitting",
9294         "Do NOT strip off any characters"
9295 };
9296
9297 static const value_string dfs_referral_server_type_vals[] = {
9298         {0,     "Don't know"},
9299         {1,     "SMB Server"},
9300         {2,     "Netware Server"},
9301         {3,     "Domain Server"},
9302         {0, NULL}
9303 };
9304
9305
9306 static const true_false_string tfs_device_char_removable = {
9307         "This is a REMOVABLE device",
9308         "This is NOT a removable device"
9309 };
9310 static const true_false_string tfs_device_char_read_only = {
9311         "This is a READ-ONLY device",
9312         "This is NOT a read-only device"
9313 };
9314 static const true_false_string tfs_device_char_floppy = {
9315         "This is a FLOPPY DISK device",
9316         "This is NOT a floppy disk device"
9317 };
9318 static const true_false_string tfs_device_char_write_once = {
9319         "This is a WRITE-ONCE device",
9320         "This is NOT a write-once device"
9321 };
9322 static const true_false_string tfs_device_char_remote = {
9323         "This is a REMOTE device",
9324         "This is NOT a remote device"
9325 };
9326 static const true_false_string tfs_device_char_mounted = {
9327         "This device is MOUNTED",
9328         "This device is NOT mounted"
9329 };
9330 static const true_false_string tfs_device_char_virtual = {
9331         "This is a VIRTUAL device",
9332         "This is NOT a virtual device"
9333 };
9334
9335
9336 static const true_false_string tfs_fs_attr_css = {
9337         "This FS supports CASE SENSITIVE SEARCHes",
9338         "This FS does NOT support case sensitive searches"
9339 };
9340 static const true_false_string tfs_fs_attr_cpn = {
9341         "This FS supports CASE PRESERVED NAMES",
9342         "This FS does NOT support case preserved names"
9343 };
9344 static const true_false_string tfs_fs_attr_pacls = {
9345         "This FS supports PERSISTENT ACLs",
9346         "This FS does NOT support persistent acls"
9347 };
9348 static const true_false_string tfs_fs_attr_fc = {
9349         "This FS supports COMPRESSED FILES",
9350         "This FS does NOT support compressed files"
9351 };
9352 static const true_false_string tfs_fs_attr_vq = {
9353         "This FS supports VOLUME QUOTAS",
9354         "This FS does NOT support volume quotas"
9355 };
9356 static const true_false_string tfs_fs_attr_dim = {
9357         "This FS is on a MOUNTED DEVICE",
9358         "This FS is NOT on a mounted device"
9359 };
9360 static const true_false_string tfs_fs_attr_vic = {
9361         "This FS is on a COMPRESSED VOLUME",
9362         "This FS is NOT on a compressed volume"
9363 };
9364
9365 #define FF2_RESUME      0x0004
9366
9367 static int
9368 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9369 {
9370         guint16 mask;
9371         proto_item *item = NULL;
9372         proto_tree *tree = NULL;
9373         smb_info_t *si;
9374         smb_transact2_info_t *t2i;
9375
9376         mask = tvb_get_letohs(tvb, offset);
9377
9378         si = (smb_info_t *)pinfo->private_data;
9379         if (si->sip != NULL) {
9380                 t2i = si->sip->extra_info;
9381                 if (t2i != NULL) {
9382                         if (!pinfo->fd->flags.visited)
9383                                 t2i->resume_keys = (mask & FF2_RESUME);
9384                 }
9385         }
9386
9387         if(parent_tree){
9388                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9389                         "Flags: 0x%04x", mask);
9390                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
9391         }
9392
9393         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
9394                 tvb, offset, 2, mask);
9395         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
9396                 tvb, offset, 2, mask);
9397         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
9398                 tvb, offset, 2, mask);
9399         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
9400                 tvb, offset, 2, mask);
9401         proto_tree_add_boolean(tree, hf_smb_ff2_close,
9402                 tvb, offset, 2, mask);
9403
9404         offset += 2;
9405
9406         return offset;
9407 }
9408
9409 #if 0
9410 static int
9411 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9412 {
9413         guint16 mask;
9414         proto_item *item = NULL;
9415         proto_tree *tree = NULL;
9416
9417         mask = tvb_get_letohs(tvb, offset);
9418
9419         if(parent_tree){
9420                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9421                         "IO Flag: 0x%04x", mask);
9422                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
9423         }
9424
9425         proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
9426                 tvb, offset, 2, mask);
9427         proto_tree_add_boolean(tree, hf_smb_sfi_caching,
9428                 tvb, offset, 2, mask);
9429
9430         offset += 2;
9431
9432         return offset;
9433 }
9434 #endif
9435
9436 static int
9437 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
9438     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
9439 {
9440         proto_item *item = NULL;
9441         proto_tree *tree = NULL;
9442         smb_info_t *si;
9443         smb_transact2_info_t *t2i;
9444         int fn_len;
9445         const char *fn;
9446         int old_offset = offset;
9447
9448         si = (smb_info_t *)pinfo->private_data;
9449         if (si->sip != NULL)
9450                 t2i = si->sip->extra_info;
9451         else
9452                 t2i = NULL;
9453
9454         if(parent_tree){
9455                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
9456                                 "%s Parameters",
9457                                 val_to_str(subcmd, trans2_cmd_vals,
9458                                            "Unknown (0x%02x)"));
9459                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
9460         }
9461
9462         switch(subcmd){
9463         case 0x00:      /*TRANS2_OPEN2*/
9464                 /* open flags */
9465                 CHECK_BYTE_COUNT_TRANS(2);
9466                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
9467                 bc -= 2;
9468
9469                 /* desired access */
9470                 CHECK_BYTE_COUNT_TRANS(2);
9471                 offset = dissect_access(tvb, tree, offset, "Desired");
9472                 bc -= 2;
9473
9474                 /* Search Attributes */
9475                 CHECK_BYTE_COUNT_TRANS(2);
9476                 offset = dissect_search_attributes(tvb, tree, offset);
9477                 bc -= 2;
9478
9479                 /* File Attributes */
9480                 CHECK_BYTE_COUNT_TRANS(2);
9481                 offset = dissect_file_attributes(tvb, tree, offset);
9482                 bc -= 2;
9483
9484                 /* create time */
9485                 CHECK_BYTE_COUNT_TRANS(4);
9486                 offset = dissect_smb_datetime(tvb, tree, offset,
9487                         hf_smb_create_time,
9488                         hf_smb_create_dos_date, hf_smb_create_dos_time,
9489                         TRUE);
9490                 bc -= 4;
9491
9492                 /* open function */
9493                 CHECK_BYTE_COUNT_TRANS(2);
9494                 offset = dissect_open_function(tvb, tree, offset);
9495                 bc -= 2;
9496
9497                 /* allocation size */
9498                 CHECK_BYTE_COUNT_TRANS(4);
9499                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
9500                 COUNT_BYTES_TRANS(4);
9501
9502                 /* 10 reserved bytes */
9503                 CHECK_BYTE_COUNT_TRANS(10);
9504                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
9505                 COUNT_BYTES_TRANS(10);
9506
9507                 /* file name */
9508                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9509                 CHECK_STRING_TRANS(fn);
9510                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9511                         fn);
9512                 COUNT_BYTES_TRANS(fn_len);
9513
9514                 if (check_col(pinfo->cinfo, COL_INFO)) {
9515                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9516                         fn);
9517                 }
9518                 break;
9519         case 0x01:      /*TRANS2_FIND_FIRST2*/
9520                 /* Search Attributes */
9521                 CHECK_BYTE_COUNT_TRANS(2);
9522                 offset = dissect_search_attributes(tvb, tree, offset);
9523                 bc -= 2;
9524
9525                 /* search count */
9526                 CHECK_BYTE_COUNT_TRANS(2);
9527                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
9528                 COUNT_BYTES_TRANS(2);
9529
9530                 /* Find First2 flags */
9531                 CHECK_BYTE_COUNT_TRANS(2);
9532                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
9533                 bc -= 2;
9534
9535                 /* Find First2 information level */
9536                 CHECK_BYTE_COUNT_TRANS(2);
9537                 si->info_level = tvb_get_letohs(tvb, offset);
9538                 if (!pinfo->fd->flags.visited)
9539                         t2i->info_level = si->info_level;
9540                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
9541                 COUNT_BYTES_TRANS(2);
9542
9543                 /* storage type */
9544                 CHECK_BYTE_COUNT_TRANS(4);
9545                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
9546                 COUNT_BYTES_TRANS(4);
9547
9548                 /* search pattern */
9549                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9550                 CHECK_STRING_TRANS(fn);
9551                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
9552                         fn);
9553                 COUNT_BYTES_TRANS(fn_len);
9554
9555                 if (check_col(pinfo->cinfo, COL_INFO)) {
9556                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
9557                         fn);
9558                 }
9559
9560                 break;
9561         case 0x02:      /*TRANS2_FIND_NEXT2*/
9562                 /* sid */
9563                 CHECK_BYTE_COUNT_TRANS(2);
9564                 proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
9565                 COUNT_BYTES_TRANS(2);
9566
9567                 /* search count */
9568                 CHECK_BYTE_COUNT_TRANS(2);
9569                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
9570                 COUNT_BYTES_TRANS(2);
9571
9572                 /* Find First2 information level */
9573                 CHECK_BYTE_COUNT_TRANS(2);
9574                 si->info_level = tvb_get_letohs(tvb, offset);
9575                 if (!pinfo->fd->flags.visited)
9576                         t2i->info_level = si->info_level;
9577                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
9578                 COUNT_BYTES_TRANS(2);
9579
9580                 /* resume key */
9581                 CHECK_BYTE_COUNT_TRANS(4);
9582                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
9583                 COUNT_BYTES_TRANS(4);
9584
9585                 /* Find First2 flags */
9586                 CHECK_BYTE_COUNT_TRANS(2);
9587                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
9588                 bc -= 2;
9589
9590                 /* file name */
9591                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9592                 CHECK_STRING_TRANS(fn);
9593                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9594                         fn);
9595                 COUNT_BYTES_TRANS(fn_len);
9596
9597                 if (check_col(pinfo->cinfo, COL_INFO)) {
9598                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
9599                         fn);
9600                 }
9601
9602                 break;
9603         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
9604                 /* level of interest */
9605                 CHECK_BYTE_COUNT_TRANS(2);
9606                 si->info_level = tvb_get_letohs(tvb, offset);
9607                 if (!pinfo->fd->flags.visited)
9608                         t2i->info_level = si->info_level;
9609                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
9610                 COUNT_BYTES_TRANS(2);
9611
9612                 break;
9613         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
9614                 /* level of interest */
9615                 CHECK_BYTE_COUNT_TRANS(2);
9616                 si->info_level = tvb_get_letohs(tvb, offset);
9617                 if (!pinfo->fd->flags.visited)
9618                         t2i->info_level = si->info_level;
9619                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9620                 COUNT_BYTES_TRANS(2);
9621
9622                 /* 4 reserved bytes */
9623                 CHECK_BYTE_COUNT_TRANS(4);
9624                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9625                 COUNT_BYTES_TRANS(4);
9626
9627                 /* file name */
9628                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9629                 CHECK_STRING_TRANS(fn);
9630                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9631                         fn);
9632                 COUNT_BYTES_TRANS(fn_len);
9633
9634                 if (check_col(pinfo->cinfo, COL_INFO)) {
9635                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9636                         fn);
9637                 }
9638
9639                 break;
9640         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
9641                 /* level of interest */
9642                 CHECK_BYTE_COUNT_TRANS(2);
9643                 si->info_level = tvb_get_letohs(tvb, offset);
9644                 if (!pinfo->fd->flags.visited)
9645                         t2i->info_level = si->info_level;
9646                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9647                 COUNT_BYTES_TRANS(2);
9648
9649                 /* 4 reserved bytes */
9650                 CHECK_BYTE_COUNT_TRANS(4);
9651                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9652                 COUNT_BYTES_TRANS(4);
9653
9654                 /* file name */
9655                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9656                 CHECK_STRING_TRANS(fn);
9657                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9658                         fn);
9659                 COUNT_BYTES_TRANS(fn_len);
9660
9661                 if (check_col(pinfo->cinfo, COL_INFO)) {
9662                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9663                         fn);
9664                 }
9665
9666                 break;
9667         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
9668                 guint16 fid;
9669
9670                 /* fid */
9671                 CHECK_BYTE_COUNT_TRANS(2);
9672                 fid = tvb_get_letohs(tvb, offset);
9673                 add_fid(tvb, pinfo, tree, offset, 2, fid);
9674                 COUNT_BYTES_TRANS(2);
9675
9676                 /* level of interest */
9677                 CHECK_BYTE_COUNT_TRANS(2);
9678                 si->info_level = tvb_get_letohs(tvb, offset);
9679                 if (!pinfo->fd->flags.visited)
9680                         t2i->info_level = si->info_level;
9681                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9682                 COUNT_BYTES_TRANS(2);
9683
9684                 break;
9685         }
9686         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
9687                 guint16 fid;
9688
9689                 /* fid */
9690                 CHECK_BYTE_COUNT_TRANS(2);
9691                 fid = tvb_get_letohs(tvb, offset);
9692                 add_fid(tvb, pinfo, tree, offset, 2, fid);
9693                 COUNT_BYTES_TRANS(2);
9694
9695                 /* level of interest */
9696                 CHECK_BYTE_COUNT_TRANS(2);
9697                 si->info_level = tvb_get_letohs(tvb, offset);
9698                 if (!pinfo->fd->flags.visited)
9699                         t2i->info_level = si->info_level;
9700                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9701                 COUNT_BYTES_TRANS(2);
9702
9703 #if 0
9704                 /*
9705                  * XXX - "Microsoft Networks SMB File Sharing Protocol
9706                  * Extensions Version 3.0, Document Version 1.11,
9707                  * July 19, 1990" says this is I/O flags, but it's
9708                  * reserved in the SNIA spec, and some clients appear
9709                  * to leave junk in it.
9710                  *
9711                  * Is this some field used only if a particular
9712                  * dialect was negotiated, so that clients can feel
9713                  * safe not setting it if they haven't negotiated that
9714                  * dialect?  Or do the (non-OS/2) clients simply not care
9715                  * about that particular OS/2-oriented dialect?
9716                  */
9717
9718                 /* IO Flag */
9719                 CHECK_BYTE_COUNT_TRANS(2);
9720                 offset = dissect_sfi_ioflag(tvb, tree, offset);
9721                 bc -= 2;
9722 #else
9723                 /* 2 reserved bytes */
9724                 CHECK_BYTE_COUNT_TRANS(2);
9725                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
9726                 COUNT_BYTES_TRANS(2);
9727 #endif
9728
9729                 break;
9730         }
9731         case 0x09:      /*TRANS2_FSCTL*/
9732                 /* this call has no parameter block in the request */
9733
9734                 /*
9735                  * XXX - "Microsoft Networks SMB File Sharing Protocol
9736                  * Extensions Version 3.0, Document Version 1.11,
9737                  * July 19, 1990" says this this contains a
9738                  * "File system specific parameter block".  (That means
9739                  * we may not be able to dissect it in any case.)
9740                  */
9741                 break;
9742         case 0x0a:      /*TRANS2_IOCTL2*/
9743                 /* this call has no parameter block in the request */
9744
9745                 /*
9746                  * XXX - "Microsoft Networks SMB File Sharing Protocol
9747                  * Extensions Version 3.0, Document Version 1.11,
9748                  * July 19, 1990" says this this contains a
9749                  * "Device/function specific parameter block".  (That
9750                  * means we may not be able to dissect it in any case.)
9751                  */
9752                 break;
9753         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
9754                 /* Search Attributes */
9755                 CHECK_BYTE_COUNT_TRANS(2);
9756                 offset = dissect_search_attributes(tvb, tree, offset);
9757                 bc -= 2;
9758
9759                 /* Number of changes to wait for */
9760                 CHECK_BYTE_COUNT_TRANS(2);
9761                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
9762                 COUNT_BYTES_TRANS(2);
9763
9764                 /* Find Notify information level */
9765                 CHECK_BYTE_COUNT_TRANS(2);
9766                 si->info_level = tvb_get_letohs(tvb, offset);
9767                 if (!pinfo->fd->flags.visited)
9768                         t2i->info_level = si->info_level;
9769                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
9770                 COUNT_BYTES_TRANS(2);
9771
9772                 /* 4 reserved bytes */
9773                 CHECK_BYTE_COUNT_TRANS(4);
9774                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9775                 COUNT_BYTES_TRANS(4);
9776
9777                 /* file name */
9778                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9779                 CHECK_STRING_TRANS(fn);
9780                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9781                         fn);
9782                 COUNT_BYTES_TRANS(fn_len);
9783
9784                 if (check_col(pinfo->cinfo, COL_INFO)) {
9785                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9786                         fn);
9787                 }
9788
9789                 break;
9790         }
9791         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
9792                 /* Monitor handle */
9793                 CHECK_BYTE_COUNT_TRANS(2);
9794                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
9795                 COUNT_BYTES_TRANS(2);
9796
9797                 /* Number of changes to wait for */
9798                 CHECK_BYTE_COUNT_TRANS(2);
9799                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
9800                 COUNT_BYTES_TRANS(2);
9801
9802                 break;
9803         }
9804         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
9805                 /* 4 reserved bytes */
9806                 CHECK_BYTE_COUNT_TRANS(4);
9807                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9808                 COUNT_BYTES_TRANS(4);
9809
9810                 /* dir name */
9811                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
9812                         FALSE, FALSE, &bc);
9813                 CHECK_STRING_TRANS(fn);
9814                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
9815                         fn);
9816                 COUNT_BYTES_TRANS(fn_len);
9817
9818                 if (check_col(pinfo->cinfo, COL_INFO)) {
9819                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
9820                         fn);
9821                 }
9822                 break;
9823         case 0x0e:      /*TRANS2_SESSION_SETUP*/
9824                 /* XXX unknown structure*/
9825                 break;
9826         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
9827                 /* referral level */
9828                 CHECK_BYTE_COUNT_TRANS(2);
9829                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
9830                 COUNT_BYTES_TRANS(2);
9831
9832                 /* file name */
9833                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9834                 CHECK_STRING_TRANS(fn);
9835                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9836                         fn);
9837                 COUNT_BYTES_TRANS(fn_len);
9838
9839                 if (check_col(pinfo->cinfo, COL_INFO)) {
9840                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
9841                         fn);
9842                 }
9843
9844                 break;
9845         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
9846                 /* file name */
9847                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9848                 CHECK_STRING_TRANS(fn);
9849                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9850                         fn);
9851                 COUNT_BYTES_TRANS(fn_len);
9852
9853                 if (check_col(pinfo->cinfo, COL_INFO)) {
9854                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
9855                         fn);
9856                 }
9857
9858                 break;
9859         }
9860
9861         /* ooops there were data we didnt know how to process */
9862         if((offset-old_offset) < bc){
9863                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
9864                     bc - (offset-old_offset), TRUE);
9865                 offset += bc - (offset-old_offset);
9866         }
9867
9868         return offset;
9869 }
9870
9871 /*
9872  * XXX - just use "dissect_connect_flags()" here?
9873  */
9874 static guint16
9875 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9876 {
9877         guint16 mask;
9878         proto_item *item = NULL;
9879         proto_tree *tree = NULL;
9880
9881         mask = tvb_get_letohs(tvb, offset);
9882
9883         if(parent_tree){
9884                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9885                         "Flags: 0x%04x", mask);
9886                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
9887         }
9888
9889         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
9890                 tvb, offset, 2, mask);
9891         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
9892                 tvb, offset, 2, mask);
9893
9894         return mask;
9895 }
9896
9897
9898 static int
9899 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9900 {
9901         guint16 mask;
9902         proto_item *item = NULL;
9903         proto_tree *tree = NULL;
9904
9905         mask = tvb_get_letohs(tvb, offset);
9906
9907         if(parent_tree){
9908                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9909                         "Flags: 0x%04x", mask);
9910                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
9911         }
9912
9913         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
9914                 tvb, offset, 2, mask);
9915         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
9916                 tvb, offset, 2, mask);
9917
9918         offset += 2;
9919         return offset;
9920 }
9921
9922 static int
9923 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
9924 {
9925         guint16 mask;
9926         proto_item *item = NULL;
9927         proto_tree *tree = NULL;
9928
9929         mask = tvb_get_letohs(tvb, offset);
9930
9931         if(parent_tree){
9932                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9933                         "Flags: 0x%04x", mask);
9934                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
9935         }
9936
9937         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
9938                 tvb, offset, 2, mask);
9939
9940         offset += 2;
9941
9942         return offset;
9943 }
9944
9945
9946 /* dfs inconsistency data  (4.4.2)
9947 */
9948 static int
9949 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
9950     proto_tree *tree, int offset, guint16 *bcp)
9951 {
9952         smb_info_t *si = pinfo->private_data;
9953         int fn_len;
9954         const char *fn;
9955
9956         /*XXX shouldn this data hold version and size? unclear from doc*/
9957         /* referral version */
9958         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9959         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
9960         COUNT_BYTES_TRANS_SUBR(2);
9961
9962         /* referral size */
9963         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9964         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
9965         COUNT_BYTES_TRANS_SUBR(2);
9966
9967         /* referral server type */
9968         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9969         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
9970         COUNT_BYTES_TRANS_SUBR(2);
9971
9972         /* referral flags */
9973         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9974         offset = dissect_dfs_referral_flags(tvb, tree, offset);
9975         *bcp -= 2;
9976
9977         /* node name */
9978         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
9979         CHECK_STRING_TRANS_SUBR(fn);
9980         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
9981                 fn);
9982         COUNT_BYTES_TRANS_SUBR(fn_len);
9983
9984         return offset;
9985 }
9986
9987 /* get dfs referral data  (4.4.1)
9988 */
9989 static int
9990 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
9991     proto_tree *tree, int offset, guint16 *bcp)
9992 {
9993         smb_info_t *si = pinfo->private_data;
9994         guint16 numref;
9995         guint16 refsize;
9996         guint16 pathoffset;
9997         guint16 altpathoffset;
9998         guint16 nodeoffset;
9999         int fn_len;
10000         int stroffset;
10001         int offsetoffset;
10002         guint16 save_bc;
10003         const char *fn;
10004         int unklen;
10005         int ucstring_end;
10006         int ucstring_len;
10007
10008         /* path consumed */
10009         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10010         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
10011         COUNT_BYTES_TRANS_SUBR(2);
10012
10013         /* num referrals */
10014         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10015         numref = tvb_get_letohs(tvb, offset);
10016         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
10017         COUNT_BYTES_TRANS_SUBR(2);
10018
10019         /* get dfs flags */
10020         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10021         offset = dissect_get_dfs_flags(tvb, tree, offset);
10022         *bcp -= 2;
10023
10024         /* XXX - in at least one capture there appears to be 2 bytes
10025            of stuff after the Dfs flags, perhaps so that the header
10026            in front of the referral list is a multiple of 4 bytes long. */
10027         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10028         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
10029         COUNT_BYTES_TRANS_SUBR(2);
10030
10031         /* if there are any referrals */
10032         if(numref){
10033                 proto_item *ref_item = NULL;
10034                 proto_tree *ref_tree = NULL;
10035                 int old_offset=offset;
10036
10037                 if(tree){
10038                         ref_item = proto_tree_add_text(tree,
10039                                 tvb, offset, *bcp, "Referrals");
10040                         ref_tree = proto_item_add_subtree(ref_item,
10041                                 ett_smb_dfs_referrals);
10042                 }
10043                 ucstring_end = -1;
10044
10045                 while(numref--){
10046                         proto_item *ri = NULL;
10047                         proto_tree *rt = NULL;
10048                         int old_offset=offset;
10049                         guint16 version;
10050
10051                         if(tree){
10052                                 ri = proto_tree_add_text(ref_tree,
10053                                         tvb, offset, *bcp, "Referral");
10054                                 rt = proto_item_add_subtree(ri,
10055                                         ett_smb_dfs_referral);
10056                         }
10057
10058                         /* referral version */
10059                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10060                         version = tvb_get_letohs(tvb, offset);
10061                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
10062                                 tvb, offset, 2, version);
10063                         COUNT_BYTES_TRANS_SUBR(2);
10064
10065                         /* referral size */
10066                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10067                         refsize = tvb_get_letohs(tvb, offset);
10068                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
10069                         COUNT_BYTES_TRANS_SUBR(2);
10070
10071                         /* referral server type */
10072                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10073                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10074                         COUNT_BYTES_TRANS_SUBR(2);
10075
10076                         /* referral flags */
10077                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10078                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
10079                         *bcp -= 2;
10080
10081                         switch(version){
10082
10083                         case 1:
10084                                 /* node name */
10085                                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10086                                 CHECK_STRING_TRANS_SUBR(fn);
10087                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10088                                         fn);
10089                                 COUNT_BYTES_TRANS_SUBR(fn_len);
10090                                 break;
10091
10092                         case 2:
10093                         case 3: /* XXX - like version 2, but not identical;
10094                                    seen in a capture, but the format isn't
10095                                    documented */
10096                                 /* proximity */
10097                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10098                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
10099                                 COUNT_BYTES_TRANS_SUBR(2);
10100
10101                                 /* ttl */
10102                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10103                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
10104                                 COUNT_BYTES_TRANS_SUBR(2);
10105
10106                                 /* path offset */
10107                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10108                                 pathoffset = tvb_get_letohs(tvb, offset);
10109                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
10110                                 COUNT_BYTES_TRANS_SUBR(2);
10111
10112                                 /* alt path offset */
10113                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10114                                 altpathoffset = tvb_get_letohs(tvb, offset);
10115                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
10116                                 COUNT_BYTES_TRANS_SUBR(2);
10117
10118                                 /* node offset */
10119                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10120                                 nodeoffset = tvb_get_letohs(tvb, offset);
10121                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
10122                                 COUNT_BYTES_TRANS_SUBR(2);
10123
10124                                 /* path */
10125                                 if (pathoffset != 0) {
10126                                         stroffset = old_offset + pathoffset;
10127                                         offsetoffset = stroffset - offset;
10128                                         if (offsetoffset > 0 &&
10129                                             *bcp > offsetoffset) {
10130                                                 save_bc = *bcp;
10131                                                 *bcp -= offsetoffset;
10132                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10133                                                 CHECK_STRING_TRANS_SUBR(fn);
10134                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
10135                                                         fn);
10136                                                 stroffset += fn_len;
10137                                                 if (ucstring_end < stroffset)
10138                                                         ucstring_end = stroffset;
10139                                                 *bcp = save_bc;
10140                                         }
10141                                 }
10142
10143                                 /* alt path */
10144                                 if (altpathoffset != 0) {
10145                                         stroffset = old_offset + altpathoffset;
10146                                         offsetoffset = stroffset - offset;
10147                                         if (offsetoffset > 0 &&
10148                                             *bcp > offsetoffset) {
10149                                                 save_bc = *bcp;
10150                                                 *bcp -= offsetoffset;
10151                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10152                                                 CHECK_STRING_TRANS_SUBR(fn);
10153                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
10154                                                         fn);
10155                                                 stroffset += fn_len;
10156                                                 if (ucstring_end < stroffset)
10157                                                         ucstring_end = stroffset;
10158                                                 *bcp = save_bc;
10159                                         }
10160                                 }
10161
10162                                 /* node */
10163                                 if (nodeoffset != 0) {
10164                                         stroffset = old_offset + nodeoffset;
10165                                         offsetoffset = stroffset - offset;
10166                                         if (offsetoffset > 0 &&
10167                                             *bcp > offsetoffset) {
10168                                                 save_bc = *bcp;
10169                                                 *bcp -= offsetoffset;
10170                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10171                                                 CHECK_STRING_TRANS_SUBR(fn);
10172                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
10173                                                         fn);
10174                                                 stroffset += fn_len;
10175                                                 if (ucstring_end < stroffset)
10176                                                         ucstring_end = stroffset;
10177                                                 *bcp = save_bc;
10178                                         }
10179                                 }
10180                                 break;
10181                         }
10182
10183                         /*
10184                          * Show anything beyond the length of the referral
10185                          * as unknown data.
10186                          */
10187                         unklen = (old_offset + refsize) - offset;
10188                         if (unklen < 0) {
10189                                 /*
10190                                  * XXX - the length is bogus.
10191                                  */
10192                                 unklen = 0;
10193                         }
10194                         if (unklen != 0) {
10195                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
10196                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
10197                                     offset, unklen, TRUE);
10198                                 COUNT_BYTES_TRANS_SUBR(unklen);
10199                         }
10200
10201                         proto_item_set_len(ri, offset-old_offset);
10202                 }
10203
10204                 /*
10205                  * Treat the offset past the end of the last Unicode
10206                  * string after the referrals (if any) as the last
10207                  * offset.
10208                  */
10209                 if (ucstring_end > offset) {
10210                         ucstring_len = ucstring_end - offset;
10211                         if (*bcp < ucstring_len)
10212                                 ucstring_len = *bcp;
10213                         offset += ucstring_len;
10214                         *bcp -= ucstring_len;
10215                 }
10216                 proto_item_set_len(ref_item, offset-old_offset);
10217         }
10218
10219         return offset;
10220 }
10221
10222
10223 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
10224    as described in 4.2.14.1
10225 */
10226 static int
10227 dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10228     int offset, guint16 *bcp, gboolean *trunc)
10229 {
10230         /* create time */
10231         CHECK_BYTE_COUNT_SUBR(4);
10232         offset = dissect_smb_datetime(tvb, tree, offset,
10233                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
10234                 FALSE);
10235         *bcp -= 4;
10236
10237         /* access time */
10238         CHECK_BYTE_COUNT_SUBR(4);
10239         offset = dissect_smb_datetime(tvb, tree, offset,
10240                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
10241                 FALSE);
10242         *bcp -= 4;
10243
10244         /* last write time */
10245         CHECK_BYTE_COUNT_SUBR(4);
10246         offset = dissect_smb_datetime(tvb, tree, offset,
10247                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
10248                 FALSE);
10249         *bcp -= 4;
10250
10251         /* data size */
10252         CHECK_BYTE_COUNT_SUBR(4);
10253         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10254         COUNT_BYTES_SUBR(4);
10255
10256         /* allocation size */
10257         CHECK_BYTE_COUNT_SUBR(4);
10258         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10259         COUNT_BYTES_SUBR(4);
10260
10261         /* File Attributes */
10262         CHECK_BYTE_COUNT_SUBR(2);
10263         offset = dissect_file_attributes(tvb, tree, offset);
10264         *bcp -= 2;
10265
10266         /* ea size */
10267         CHECK_BYTE_COUNT_SUBR(4);
10268         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10269         COUNT_BYTES_SUBR(4);
10270
10271         *trunc = FALSE;
10272         return offset;
10273 }
10274
10275 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
10276    as described in 4.2.14.2
10277 */
10278 static int
10279 dissect_4_2_14_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10280     int offset, guint16 *bcp, gboolean *trunc)
10281 {
10282         /* list length */
10283         CHECK_BYTE_COUNT_SUBR(4);
10284         proto_tree_add_item(tree, hf_smb_list_length, tvb, offset, 4, TRUE);
10285         COUNT_BYTES_SUBR(4);
10286
10287         *trunc = FALSE;
10288         return offset;
10289 }
10290
10291 /* this dissects the SMB_INFO_IS_NAME_VALID
10292    as described in 4.2.14.3
10293 */
10294 static int
10295 dissect_4_2_14_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10296     int offset, guint16 *bcp, gboolean *trunc)
10297 {
10298         smb_info_t *si = pinfo->private_data;
10299         int fn_len;
10300         const char *fn;
10301
10302         /* file name */
10303         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10304         CHECK_STRING_SUBR(fn);
10305         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10306                 fn);
10307         COUNT_BYTES_SUBR(fn_len);
10308
10309         *trunc = FALSE;
10310         return offset;
10311 }
10312
10313 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
10314    as described in 4.2.14.4
10315 */
10316 static int
10317 dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10318     int offset, guint16 *bcp, gboolean *trunc)
10319 {
10320         /* create time */
10321         CHECK_BYTE_COUNT_SUBR(8);
10322         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
10323         *bcp -= 8;
10324
10325         /* access time */
10326         CHECK_BYTE_COUNT_SUBR(8);
10327         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
10328         *bcp -= 8;
10329
10330         /* last write time */
10331         CHECK_BYTE_COUNT_SUBR(8);
10332         offset = dissect_smb_64bit_time(tvb, tree, offset,
10333                 hf_smb_last_write_time);
10334         *bcp -= 8;
10335
10336         /* last change time */
10337         CHECK_BYTE_COUNT_SUBR(8);
10338         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
10339         *bcp -= 8;
10340
10341         /* File Attributes */
10342         CHECK_BYTE_COUNT_SUBR(2);
10343         offset = dissect_file_attributes(tvb, tree, offset);
10344         *bcp -= 2;
10345
10346         *trunc = FALSE;
10347         return offset;
10348 }
10349
10350 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
10351    as described in 4.2.14.5
10352 */
10353 static int
10354 dissect_4_2_14_5(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10355     int offset, guint16 *bcp, gboolean *trunc)
10356 {
10357         /* allocation size */
10358         CHECK_BYTE_COUNT_SUBR(8);
10359         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10360         COUNT_BYTES_SUBR(8);
10361
10362         /* end of file */
10363         CHECK_BYTE_COUNT_SUBR(8);
10364         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10365         COUNT_BYTES_SUBR(8);
10366
10367         /* number of links */
10368         CHECK_BYTE_COUNT_SUBR(4);
10369         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
10370         COUNT_BYTES_SUBR(4);
10371
10372         /* delete pending */
10373         CHECK_BYTE_COUNT_SUBR(2);
10374         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 2, TRUE);
10375         COUNT_BYTES_SUBR(2);
10376
10377         /* is directory */
10378         CHECK_BYTE_COUNT_SUBR(1);
10379         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
10380         COUNT_BYTES_SUBR(1);
10381
10382         *trunc = FALSE;
10383         return offset;
10384 }
10385
10386 /* this dissects the SMB_QUERY_FILE_EA_INFO
10387    as described in 4.2.14.6
10388 */
10389 static int
10390 dissect_4_2_14_6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10391     int offset, guint16 *bcp, gboolean *trunc)
10392 {
10393         /* ea size */
10394         CHECK_BYTE_COUNT_SUBR(4);
10395         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10396         COUNT_BYTES_SUBR(4);
10397
10398         *trunc = FALSE;
10399         return offset;
10400 }
10401
10402 /* this dissects the SMB_QUERY_FILE_NAME_INFO
10403    as described in 4.2.14.7
10404    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
10405    as described in 4.2.14.9
10406 */
10407 static int
10408 dissect_4_2_14_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10409     int offset, guint16 *bcp, gboolean *trunc)
10410 {
10411         smb_info_t *si = pinfo->private_data;
10412         int fn_len;
10413         const char *fn;
10414
10415         /* file name len */
10416         CHECK_BYTE_COUNT_SUBR(4);
10417         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
10418         COUNT_BYTES_SUBR(4);
10419
10420         /* file name */
10421         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10422         CHECK_STRING_SUBR(fn);
10423         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10424                 fn);
10425         COUNT_BYTES_SUBR(fn_len);
10426
10427         *trunc = FALSE;
10428         return offset;
10429 }
10430
10431 /* this dissects the SMB_QUERY_FILE_ALL_INFO
10432    as described in 4.2.14.8
10433 */
10434 static int
10435 dissect_4_2_14_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10436     int offset, guint16 *bcp, gboolean *trunc)
10437 {
10438
10439         offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp, trunc);
10440         if (*trunc) {
10441                 return offset;
10442         }
10443         offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp, trunc);
10444         if (*trunc) {
10445                 return offset;
10446         }
10447
10448         /* index number */
10449         CHECK_BYTE_COUNT_SUBR(8);
10450         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
10451         COUNT_BYTES_SUBR(8);
10452
10453         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
10454         if (*trunc)
10455                 return offset;
10456
10457         /* access flags */
10458         CHECK_BYTE_COUNT_SUBR(4);
10459         offset = dissect_nt_access_mask(tvb, tree, offset);
10460         COUNT_BYTES_SUBR(4);
10461
10462         /* index number */
10463         CHECK_BYTE_COUNT_SUBR(8);
10464         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
10465         COUNT_BYTES_SUBR(8);
10466
10467         /* current offset */
10468         CHECK_BYTE_COUNT_SUBR(8);
10469         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
10470         COUNT_BYTES_SUBR(8);
10471
10472         /* mode */
10473         CHECK_BYTE_COUNT_SUBR(4);
10474         offset = dissect_nt_create_options(tvb, tree, offset);
10475         *bcp -= 4;
10476
10477         /* alignment */
10478         CHECK_BYTE_COUNT_SUBR(4);
10479         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
10480         COUNT_BYTES_SUBR(4);
10481
10482         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
10483
10484         return offset;
10485 }
10486
10487 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
10488    as described in 4.2.14.10
10489 */
10490 static int
10491 dissect_4_2_14_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10492     int offset, guint16 *bcp, gboolean *trunc)
10493 {
10494         proto_item *item;
10495         proto_tree *tree;
10496         int old_offset;
10497         guint32 neo;
10498         smb_info_t *si = pinfo->private_data;
10499         int fn_len;
10500         const char *fn;
10501         int padcnt;
10502
10503         for (;;) {
10504                 old_offset = offset;
10505
10506                 /* next entry offset */
10507                 CHECK_BYTE_COUNT_SUBR(4);
10508                 if(parent_tree){
10509                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
10510                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10511                 } else {
10512                         item = NULL;
10513                         tree = NULL;
10514                 }
10515
10516                 neo = tvb_get_letohl(tvb, offset);
10517                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10518                 COUNT_BYTES_SUBR(4);
10519
10520                 /* stream name len */
10521                 CHECK_BYTE_COUNT_SUBR(4);
10522                 fn_len = tvb_get_letohl(tvb, offset);
10523                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
10524                 COUNT_BYTES_SUBR(4);
10525
10526                 /* stream size */
10527                 CHECK_BYTE_COUNT_SUBR(8);
10528                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
10529                 COUNT_BYTES_SUBR(8);
10530
10531                 /* allocation size */
10532                 CHECK_BYTE_COUNT_SUBR(8);
10533                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10534                 COUNT_BYTES_SUBR(8);
10535
10536                 /* stream name */
10537                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
10538                 CHECK_STRING_SUBR(fn);
10539                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
10540                         fn);
10541                 COUNT_BYTES_SUBR(fn_len);
10542
10543                 proto_item_append_text(item, ": %s", fn);
10544                 proto_item_set_len(item, offset-old_offset);
10545
10546                 if (neo == 0)
10547                         break;  /* no more structures */
10548
10549                 /* skip to next structure */
10550                 padcnt = (old_offset + neo) - offset;
10551                 if (padcnt < 0) {
10552                         /*
10553                          * XXX - this is bogus; flag it?
10554                          */
10555                         padcnt = 0;
10556                 }
10557                 if (padcnt != 0) {
10558                         CHECK_BYTE_COUNT_SUBR(padcnt);
10559                         COUNT_BYTES_SUBR(padcnt);
10560                 }
10561         }
10562
10563         *trunc = FALSE;
10564         return offset;
10565 }
10566
10567 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
10568    as described in 4.2.14.11
10569 */
10570 static int
10571 dissect_4_2_14_11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10572     int offset, guint16 *bcp, gboolean *trunc)
10573 {
10574         /* compressed file size */
10575         CHECK_BYTE_COUNT_SUBR(8);
10576         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
10577         COUNT_BYTES_SUBR(8);
10578
10579         /* compression format */
10580         CHECK_BYTE_COUNT_SUBR(2);
10581         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
10582         COUNT_BYTES_SUBR(2);
10583
10584         /* compression unit shift */
10585         CHECK_BYTE_COUNT_SUBR(1);
10586         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
10587         COUNT_BYTES_SUBR(1);
10588
10589         /* compression chunk shift */
10590         CHECK_BYTE_COUNT_SUBR(1);
10591         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
10592         COUNT_BYTES_SUBR(1);
10593
10594         /* compression cluster shift */
10595         CHECK_BYTE_COUNT_SUBR(1);
10596         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
10597         COUNT_BYTES_SUBR(1);
10598
10599         /* 3 reserved bytes */
10600         CHECK_BYTE_COUNT_SUBR(3);
10601         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
10602         COUNT_BYTES_SUBR(3);
10603
10604         *trunc = FALSE;
10605         return offset;
10606 }
10607
10608
10609
10610 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION*/
10611 static int
10612 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
10613     int offset, guint16 *bcp)
10614 {
10615         smb_info_t *si;
10616         gboolean trunc;
10617
10618         if(!*bcp){
10619                 return offset;
10620         }
10621
10622         si = (smb_info_t *)pinfo->private_data;
10623         switch(si->info_level){
10624         case 1:         /*Info Standard*/
10625         case 2:         /*Info Query EA Size*/
10626                 offset = dissect_4_2_14_1(tvb, pinfo, tree, offset, bcp,
10627                     &trunc);
10628                 break;
10629         case 3:         /*Info Query EAs From List*/
10630         case 4:         /*Info Query All EAs*/
10631                 offset = dissect_4_2_14_2(tvb, pinfo, tree, offset, bcp,
10632                     &trunc);
10633                 break;
10634         case 6:         /*Info Is Name Valid*/
10635                 offset = dissect_4_2_14_3(tvb, pinfo, tree, offset, bcp,
10636                     &trunc);
10637                 break;
10638         case 0x0101:    /*Query File Basic Info*/
10639         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
10640                 offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp,
10641                     &trunc);
10642                 break;
10643         case 0x0102:    /*Query File Standard Info*/
10644         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
10645                 offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp,
10646                     &trunc);
10647                 break;
10648         case 0x0103:    /*Query File EA Info*/
10649         case 1007:      /* SMB_FILE_EA_INFORMATION */
10650                 offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp,
10651                     &trunc);
10652                 break;
10653         case 0x0104:    /*Query File Name Info*/
10654         case 1009:      /* SMB_FILE_NAME_INFORMATION */
10655                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
10656                     &trunc);
10657                 break;
10658         case 0x0107:    /*Query File All Info*/
10659         case 1018:      /* SMB_FILE_ALL_INFORMATION */
10660                 offset = dissect_4_2_14_8(tvb, pinfo, tree, offset, bcp,
10661                     &trunc);
10662                 break;
10663         case 0x0108:    /*Query File Alt File Info*/
10664         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
10665                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
10666                     &trunc);
10667                 break;
10668         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
10669                 ((smb_info_t *)(pinfo->private_data))->unicode = TRUE;
10670         case 0x0109:    /*Query File Stream Info*/
10671                 offset = dissect_4_2_14_10(tvb, pinfo, tree, offset, bcp,
10672                     &trunc);
10673                 break;
10674         case 0x010b:    /*Query File Compression Info*/
10675         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
10676                 offset = dissect_4_2_14_11(tvb, pinfo, tree, offset, bcp,
10677                     &trunc);
10678                 break;
10679         case 0x0200:    /*Set File Unix Basic*/
10680                 /* XXX add this from the SNIA doc */
10681                 break;
10682         case 0x0201:    /*Set File Unix Link*/
10683                 /* XXX add this from the SNIA doc */
10684                 break;
10685         case 0x0202:    /*Set File Unix HardLink*/
10686                 /* XXX add this from the SNIA doc */
10687                 break;
10688         }
10689
10690         return offset;
10691 }
10692
10693
10694 static const true_false_string tfs_quota_flags_deny_disk = {
10695         "DENY DISK SPACE for users exceeding quota limit",
10696         "Do NOT deny disk space for users exceeding quota limit"
10697 };
10698 static const true_false_string tfs_quota_flags_log_limit = {
10699         "LOG EVENT when a user exceeds their QUOTA LIMIT",
10700         "Do NOT log event when a user exceeds their quota limit"
10701 };
10702 static const true_false_string tfs_quota_flags_log_warning = {
10703         "LOG EVENT when a user exceeds their WARNING LEVEL",
10704         "Do NOT log event when a user exceeds their warning level"
10705 };
10706 static const true_false_string tfs_quota_flags_enabled = {
10707         "Quotas are ENABLED of this fs",
10708         "Quotas are NOT enabled on this fs"
10709 };
10710 static void
10711 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10712 {
10713         guint8 mask;
10714         proto_item *item = NULL;
10715         proto_tree *tree = NULL;
10716
10717         mask = tvb_get_guint8(tvb, offset);
10718
10719         if(parent_tree){
10720                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
10721                         "Quota Flags: 0x%02x %s", mask,
10722                         mask?"Enabled":"Disabled");
10723                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
10724         }
10725
10726         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
10727                 tvb, offset, 1, mask);
10728         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
10729                 tvb, offset, 1, mask);
10730         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
10731                 tvb, offset, 1, mask);
10732
10733         if(mask && (!(mask&0x01))){
10734                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
10735                         tvb, offset, 1, 0x01);
10736         } else {
10737                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
10738                         tvb, offset, 1, mask);
10739         }
10740
10741 }
10742
10743 static int
10744 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
10745 {
10746         /* first 24 bytes are unknown */
10747         CHECK_BYTE_COUNT_TRANS_SUBR(24);
10748         proto_tree_add_item(tree, hf_smb_unknown, tvb,
10749                     offset, 24, TRUE);
10750         COUNT_BYTES_TRANS_SUBR(24);
10751
10752         /* number of bytes for quota warning */
10753         CHECK_BYTE_COUNT_TRANS_SUBR(8);
10754         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
10755         COUNT_BYTES_TRANS_SUBR(8);
10756
10757         /* number of bytes for quota limit */
10758         CHECK_BYTE_COUNT_TRANS_SUBR(8);
10759         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
10760         COUNT_BYTES_TRANS_SUBR(8);
10761
10762         /* one byte of quota flags */
10763         CHECK_BYTE_COUNT_TRANS_SUBR(1);
10764         dissect_quota_flags(tvb, tree, offset);
10765         COUNT_BYTES_TRANS_SUBR(1);
10766
10767         /* these 7 bytes are unknown */
10768         CHECK_BYTE_COUNT_TRANS_SUBR(7);
10769         proto_tree_add_item(tree, hf_smb_unknown, tvb,
10770                     offset, 7, TRUE);
10771         COUNT_BYTES_TRANS_SUBR(7);
10772
10773         return offset;
10774 }
10775
10776 static int
10777 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
10778     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
10779 {
10780         proto_item *item = NULL;
10781         proto_tree *tree = NULL;
10782         smb_info_t *si;
10783
10784         si = (smb_info_t *)pinfo->private_data;
10785
10786         if(parent_tree){
10787                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
10788                                 "%s Data",
10789                                 val_to_str(subcmd, trans2_cmd_vals,
10790                                                 "Unknown (0x%02x)"));
10791                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
10792         }
10793
10794         switch(subcmd){
10795         case 0x00:      /*TRANS2_OPEN2*/
10796                 /* XXX dont know how to decode FEAList */
10797                 break;
10798         case 0x01:      /*TRANS2_FIND_FIRST2*/
10799                 /* XXX dont know how to decode FEAList */
10800                 break;
10801         case 0x02:      /*TRANS2_FIND_NEXT2*/
10802                 /* XXX dont know how to decode FEAList */
10803                 break;
10804         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10805                 /* no data field in this request */
10806                 break;
10807         case 0x04:      /* TRANS2_SET_QUOTA */
10808                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
10809                 break;
10810         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10811                 /* no data field in this request */
10812                 /*
10813                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10814                  * Extensions Version 3.0, Document Version 1.11,
10815                  * July 19, 1990" says there may be "Additional
10816                  * FileInfoLevel dependent information" here.
10817                  *
10818                  * Was that just a cut-and-pasteo?
10819                  * TRANS2_SET_PATH_INFORMATION *does* have that information
10820                  * here.
10821                  */
10822                 break;
10823         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10824                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
10825                 break;
10826         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
10827                 /* no data field in this request */
10828                 /*
10829                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10830                  * Extensions Version 3.0, Document Version 1.11,
10831                  * July 19, 1990" says there may be "Additional
10832                  * FileInfoLevel dependent information" here.
10833                  *
10834                  * Was that just a cut-and-pasteo?
10835                  * TRANS2_SET_FILE_INFORMATION *does* have that information
10836                  * here.
10837                  */
10838                 break;
10839         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
10840                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
10841                 break;
10842         case 0x09:      /*TRANS2_FSCTL*/
10843                 /*XXX dont know how to decode this yet */
10844
10845                 /*
10846                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10847                  * Extensions Version 3.0, Document Version 1.11,
10848                  * July 19, 1990" says this this contains a
10849                  * "File system specific data block".  (That means we
10850                  * may not be able to dissect it in any case.)
10851                  */
10852                 break;
10853         case 0x0a:      /*TRANS2_IOCTL2*/
10854                 /*XXX dont know how to decode this yet */
10855
10856                 /*
10857                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10858                  * Extensions Version 3.0, Document Version 1.11,
10859                  * July 19, 1990" says this this contains a
10860                  * "Device/function specific data block".  (That
10861                  * means we may not be able to dissect it in any case.)
10862                  */
10863                 break;
10864         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
10865                 /*XXX dont know how to decode this yet */
10866
10867                 /*
10868                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10869                  * Extensions Version 3.0, Document Version 1.11,
10870                  * July 19, 1990" says this this contains "additional
10871                  * level dependent match data".
10872                  */
10873                 break;
10874         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
10875                 /*XXX dont know how to decode this yet */
10876
10877                 /*
10878                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10879                  * Extensions Version 3.0, Document Version 1.11,
10880                  * July 19, 1990" says this this contains "additional
10881                  * level dependent monitor information".
10882                  */
10883                 break;
10884         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10885                 /* XXX optional FEAList, unknown what FEAList looks like*/
10886                 break;
10887         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10888                 /*XXX dont know how to decode this yet */
10889                 break;
10890         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10891                 /* no data field in this request */
10892                 break;
10893         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10894                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
10895                 break;
10896         }
10897
10898         /* ooops there were data we didnt know how to process */
10899         if(dc != 0){
10900                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
10901                 offset += dc;
10902         }
10903
10904         return offset;
10905 }
10906
10907
10908 static void
10909 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
10910     proto_tree *tree)
10911 {
10912         int i;
10913         int offset;
10914         guint length;
10915
10916         /*
10917          * Show the setup words.
10918          */
10919         if (s_tvb != NULL) {
10920                 length = tvb_reported_length(s_tvb);
10921                 for (i = 0, offset = 0; length >= 2;
10922                     i++, offset += 2, length -= 2) {
10923                         /*
10924                          * XXX - add a setup word filterable field?
10925                          */
10926                         proto_tree_add_text(tree, s_tvb, offset, 2,
10927                             "Setup Word %d: 0x%04x", i,
10928                             tvb_get_letohs(s_tvb, offset));
10929                 }
10930         }
10931
10932         /*
10933          * Show the parameters, if any.
10934          */
10935         if (p_tvb != NULL) {
10936                 length = tvb_reported_length(p_tvb);
10937                 if (length != 0) {
10938                         proto_tree_add_text(tree, p_tvb, 0, length,
10939                             "Parameters: %s",
10940                             tvb_bytes_to_str(p_tvb, 0, length));
10941                 }
10942         }
10943
10944         /*
10945          * Show the data, if any.
10946          */
10947         if (d_tvb != NULL) {
10948                 length = tvb_reported_length(d_tvb);
10949                 if (length != 0) {
10950                         proto_tree_add_text(tree, d_tvb, 0, length,
10951                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
10952                 }
10953         }
10954 }
10955
10956 /* This routine handles the following 4 calls
10957    Transaction  0x25
10958    Transaction Secondary 0x26
10959    Transaction2 0x32
10960    Transaction2 Secondary 0x33
10961 */
10962 static int
10963 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
10964 {
10965         guint8 wc, sc=0;
10966         int so=offset;
10967         int sl=0;
10968         int spo=offset;
10969         int spc=0;
10970         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
10971         int subcmd = -1;
10972         guint32 to;
10973         int an_len;
10974         const char *an = NULL;
10975         smb_info_t *si;
10976         smb_transact2_info_t *t2i;
10977         smb_transact_info_t *tri;
10978         guint16 bc;
10979         int padcnt;
10980         gboolean dissected_trans;
10981
10982         si = (smb_info_t *)pinfo->private_data;
10983
10984         WORD_COUNT;
10985
10986         if(wc==8){
10987                 /*secondary client request*/
10988
10989                 /* total param count, only a 16bit integer here*/
10990                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10991                 offset += 2;
10992
10993                 /* total data count , only 16bit integer here*/
10994                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10995                 offset += 2;
10996
10997                 /* param count */
10998                 pc = tvb_get_letohs(tvb, offset);
10999                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11000                 offset += 2;
11001
11002                 /* param offset */
11003                 po = tvb_get_letohs(tvb, offset);
11004                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11005                 offset += 2;
11006
11007                 /* param disp */
11008                 pd = tvb_get_letohs(tvb, offset);
11009                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
11010                 offset += 2;
11011
11012                 /* data count */
11013                 dc = tvb_get_letohs(tvb, offset);
11014                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11015                 offset += 2;
11016
11017                 /* data offset */
11018                 od = tvb_get_letohs(tvb, offset);
11019                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11020                 offset += 2;
11021
11022                 /* data disp */
11023                 dd = tvb_get_letohs(tvb, offset);
11024                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
11025                 offset += 2;
11026
11027                 if(si->cmd==SMB_COM_TRANSACTION2){
11028                         guint16 fid;
11029
11030                         /* fid */
11031                         fid = tvb_get_letohs(tvb, offset);
11032                         add_fid(tvb, pinfo, tree, offset, 2, fid);
11033
11034                         offset += 2;
11035                 }
11036
11037                 /* There are no setup words. */
11038                 so = offset;
11039                 sc = 0;
11040                 sl = 0;
11041         } else {
11042                 /* it is not a secondary request */
11043
11044                 /* total param count , only a 16 bit integer here*/
11045                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11046                 offset += 2;
11047
11048                 /* total data count , only 16bit integer here*/
11049                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11050                 offset += 2;
11051
11052                 /* max param count , only 16bit integer here*/
11053                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11054                 offset += 2;
11055
11056                 /* max data count, only 16bit integer here*/
11057                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11058                 offset += 2;
11059
11060                 /* max setup count, only 16bit integer here*/
11061                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
11062                 offset += 1;
11063
11064                 /* reserved byte */
11065                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11066                 offset += 1;
11067
11068                 /* transaction flags */
11069                 tf = dissect_transaction_flags(tvb, tree, offset);
11070                 offset += 2;
11071
11072                 /* timeout */
11073                 to = tvb_get_letohl(tvb, offset);
11074                 if (to == 0)
11075                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
11076                 else if (to == 0xffffffff)
11077                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
11078                 else
11079                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
11080                 offset += 4;
11081
11082                 /* 2 reserved bytes */
11083                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
11084                 offset += 2;
11085
11086                 /* param count */
11087                 pc = tvb_get_letohs(tvb, offset);
11088                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11089                 offset += 2;
11090
11091                 /* param offset */
11092                 po = tvb_get_letohs(tvb, offset);
11093                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11094                 offset += 2;
11095
11096                 /* param displacement is zero here */
11097                 pd = 0;
11098
11099                 /* data count */
11100                 dc = tvb_get_letohs(tvb, offset);
11101                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11102                 offset += 2;
11103
11104                 /* data offset */
11105                 od = tvb_get_letohs(tvb, offset);
11106                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11107                 offset += 2;
11108
11109                 /* data displacement is zero here */
11110                 dd = 0;
11111
11112                 /* setup count */
11113                 sc = tvb_get_guint8(tvb, offset);
11114                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
11115                 offset += 1;
11116
11117                 /* reserved byte */
11118                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11119                 offset += 1;
11120
11121                 /* this is where the setup bytes, if any start */
11122                 so = offset;
11123                 sl = sc*2;
11124
11125                 /* if there were any setup bytes, decode them */
11126                 if(sc){
11127                         switch(si->cmd){
11128
11129                         case SMB_COM_TRANSACTION2:
11130                                 /* TRANSACTION2 only has one setup word and
11131                                    that is the subcommand code.
11132
11133                                    XXX - except for TRANS2_FSCTL
11134                                    and TRANS2_IOCTL. */
11135                                 subcmd = tvb_get_letohs(tvb, offset);
11136                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
11137                                     tvb, offset, 2, subcmd);
11138                                 if (check_col(pinfo->cinfo, COL_INFO)) {
11139                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11140                                             val_to_str(subcmd, trans2_cmd_vals,
11141                                                 "Unknown (0x%02x)"));
11142                                 }
11143                                 if (!si->unidir) {
11144                                         if(!pinfo->fd->flags.visited){
11145                                                 /*
11146                                                  * Allocate a new
11147                                                  * smb_transact2_info_t
11148                                                  * structure.
11149                                                  */
11150                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
11151                                                 t2i->subcmd = subcmd;
11152                                                 t2i->info_level = -1;
11153                                                 t2i->resume_keys = FALSE;
11154                                                 si->sip->extra_info = t2i;
11155                                         }
11156                                 }
11157
11158                                 /*
11159                                  * XXX - process TRANS2_FSCTL and
11160                                  * TRANS2_IOCTL setup words here.
11161                                  */
11162                                 break;
11163
11164                         case SMB_COM_TRANSACTION:
11165                                 /* TRANSACTION setup words processed below */
11166                                 break;
11167                         }
11168
11169                         offset += sl;
11170                 }
11171         }
11172
11173         BYTE_COUNT;
11174
11175         if(wc!=8){
11176                 /* primary request */
11177                 /* name is NULL if transaction2 */
11178                 if(si->cmd == SMB_COM_TRANSACTION){
11179                         /* Transaction Name */
11180                         an = get_unicode_or_ascii_string(tvb, &offset,
11181                                 si->unicode, &an_len, FALSE, FALSE, &bc);
11182                         if (an == NULL)
11183                                 goto endofcommand;
11184                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
11185                                 offset, an_len, an);
11186                         COUNT_BYTES(an_len);
11187                 }
11188         }
11189
11190         /*
11191          * The pipe or mailslot arguments for Transaction start with
11192          * the first setup word (or where the first setup word would
11193          * be if there were any setup words), and run to the current
11194          * offset (which could mean that there aren't any).
11195          */
11196         spo = so;
11197         spc = offset - spo;
11198
11199         /* parameters */
11200         if(po>offset){
11201                 /* We have some initial padding bytes.
11202                 */
11203                 padcnt = po-offset;
11204                 if (padcnt > bc)
11205                         padcnt = bc;
11206                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11207                 COUNT_BYTES(padcnt);
11208         }
11209         if(pc){
11210                 CHECK_BYTE_COUNT(pc);
11211                 switch(si->cmd) {
11212
11213                 case SMB_COM_TRANSACTION2:
11214                         /* TRANSACTION2 parameters*/
11215                         offset = dissect_transaction2_request_parameters(tvb,
11216                             pinfo, tree, offset, subcmd, pc);
11217                         bc -= pc;
11218                         break;
11219
11220                 case SMB_COM_TRANSACTION:
11221                         /* TRANSACTION parameters processed below */
11222                         COUNT_BYTES(pc);
11223                         break;
11224                 }
11225         }
11226
11227         /* data */
11228         if(od>offset){
11229                 /* We have some initial padding bytes.
11230                 */
11231                 padcnt = od-offset;
11232                 if (padcnt > bc)
11233                         padcnt = bc;
11234                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11235                 COUNT_BYTES(padcnt);
11236         }
11237         if(dc){
11238                 CHECK_BYTE_COUNT(dc);
11239                 switch(si->cmd){
11240
11241                 case SMB_COM_TRANSACTION2:
11242                         /* TRANSACTION2 data*/
11243                         offset = dissect_transaction2_request_data(tvb, pinfo,
11244                             tree, offset, subcmd, dc);
11245                         bc -= dc;
11246                         break;
11247
11248                 case SMB_COM_TRANSACTION:
11249                         /* TRANSACTION data processed below */
11250                         COUNT_BYTES(dc);
11251                         break;
11252                 }
11253         }
11254
11255         /*TRANSACTION request parameters */
11256         if(si->cmd==SMB_COM_TRANSACTION){
11257                 /*XXX replace this block with a function and use that one
11258                      for both requests/responses*/
11259                 if(dd==0){
11260                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
11261                         tvbuff_t *sp_tvb, *pd_tvb;
11262
11263                         if(pc>0){
11264                                 if(pc>tvb_length_remaining(tvb, po)){
11265                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
11266                                 } else {
11267                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
11268                                 }
11269                         } else {
11270                                 p_tvb = NULL;
11271                         }
11272                         if(dc>0){
11273                                 if(dc>tvb_length_remaining(tvb, od)){
11274                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
11275                                 } else {
11276                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
11277                                 }
11278                         } else {
11279                                 d_tvb = NULL;
11280                         }
11281                         if(sl){
11282                                 if(sl>tvb_length_remaining(tvb, so)){
11283                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
11284                                 } else {
11285                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
11286                                 }
11287                         } else {
11288                                 s_tvb = NULL;
11289                         }
11290
11291                         if (!si->unidir) {
11292                                 if(!pinfo->fd->flags.visited){
11293                                         /*
11294                                          * Allocate a new smb_transact_info_t
11295                                          * structure.
11296                                          */
11297                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
11298                                         tri->subcmd = -1;
11299                                         tri->trans_subcmd = -1;
11300                                         tri->function = -1;
11301                                         tri->fid = -1;
11302                                         tri->lanman_cmd = 0;
11303                                         tri->param_descrip = NULL;
11304                                         tri->data_descrip = NULL;
11305                                         tri->aux_data_descrip = NULL;
11306                                         tri->info_level = -1;
11307                                         si->sip->extra_info = tri;
11308                                 } else {
11309                                         /*
11310                                          * We already filled the structure
11311                                          * in; don't bother doing so again.
11312                                          */
11313                                         tri = NULL;
11314                                 }
11315                         } else {
11316                                 /*
11317                                  * This is a unidirectional message, for
11318                                  * which there will be no reply; don't
11319                                  * bother allocating an "smb_transact_info_t"
11320                                  * structure for it.
11321                                  */
11322                                 tri = NULL;
11323                         }
11324                         dissected_trans = FALSE;
11325                         if(strncmp("\\PIPE\\", an, 6) == 0){
11326                                 if (tri != NULL)
11327                                         tri->subcmd=TRANSACTION_PIPE;
11328
11329                                 /*
11330                                  * A tvbuff containing the setup words and
11331                                  * the pipe path.
11332                                  */
11333                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
11334
11335                                 /*
11336                                  * A tvbuff containing the parameters and the
11337                                  * data.
11338                                  */
11339                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
11340
11341                                 dissected_trans = dissect_pipe_smb(sp_tvb,
11342                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
11343                                     top_tree);
11344                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
11345                                 if (tri != NULL)
11346                                         tri->subcmd=TRANSACTION_MAILSLOT;
11347
11348                                 /*
11349                                  * A tvbuff containing the setup words and
11350                                  * the mailslot path.
11351                                  */
11352                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
11353                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
11354                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
11355                         }
11356                         if (!dissected_trans)
11357                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
11358                 } else {
11359                         if(check_col(pinfo->cinfo, COL_INFO)){
11360                                 col_append_str(pinfo->cinfo, COL_INFO,
11361                                         "[transact continuation]");
11362                         }
11363                 }
11364         }
11365
11366         END_OF_SMB
11367
11368         return offset;
11369 }
11370
11371
11372
11373 static int
11374 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11375     int offset, guint16 *bcp, gboolean *trunc)
11376 {
11377         int fn_len;
11378         const char *fn;
11379         int old_offset = offset;
11380         proto_item *item = NULL;
11381         proto_tree *tree = NULL;
11382         smb_info_t *si;
11383         smb_transact2_info_t *t2i;
11384         gboolean resume_keys = FALSE;
11385
11386         si = (smb_info_t *)pinfo->private_data;
11387         if (si->sip != NULL) {
11388                 t2i = si->sip->extra_info;
11389                 if (t2i != NULL)
11390                         resume_keys = t2i->resume_keys;
11391         }
11392
11393         if(parent_tree){
11394                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11395                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11396                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11397         }
11398
11399         if (resume_keys) {
11400                 /* resume key */
11401                 CHECK_BYTE_COUNT_SUBR(4);
11402                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
11403                 COUNT_BYTES_SUBR(4);
11404         }
11405
11406         /* create time */
11407         CHECK_BYTE_COUNT_SUBR(4);
11408         offset = dissect_smb_datetime(tvb, tree, offset,
11409                 hf_smb_create_time,
11410                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
11411         *bcp -= 4;
11412
11413         /* access time */
11414         CHECK_BYTE_COUNT_SUBR(4);
11415         offset = dissect_smb_datetime(tvb, tree, offset,
11416                 hf_smb_access_time,
11417                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
11418         *bcp -= 4;
11419
11420         /* last write time */
11421         CHECK_BYTE_COUNT_SUBR(4);
11422         offset = dissect_smb_datetime(tvb, tree, offset,
11423                 hf_smb_last_write_time,
11424                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
11425         *bcp -= 4;
11426
11427         /* data size */
11428         CHECK_BYTE_COUNT_SUBR(4);
11429         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11430         COUNT_BYTES_SUBR(4);
11431
11432         /* allocation size */
11433         CHECK_BYTE_COUNT_SUBR(4);
11434         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
11435         COUNT_BYTES_SUBR(4);
11436
11437         /* File Attributes */
11438         CHECK_BYTE_COUNT_SUBR(2);
11439         offset = dissect_file_attributes(tvb, tree, offset);
11440         *bcp -= 2;
11441
11442         /* file name len */
11443         CHECK_BYTE_COUNT_SUBR(1);
11444         fn_len = tvb_get_guint8(tvb, offset);
11445         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
11446         COUNT_BYTES_SUBR(1);
11447         if (si->unicode)
11448                 fn_len += 2;    /* include terminating '\0' */
11449         else
11450                 fn_len++;       /* include terminating '\0' */
11451
11452         /* file name */
11453         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11454         CHECK_STRING_SUBR(fn);
11455         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11456                 fn);
11457         COUNT_BYTES_SUBR(fn_len);
11458
11459         if (check_col(pinfo->cinfo, COL_INFO)) {
11460                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11461                 fn);
11462         }
11463
11464         proto_item_append_text(item, " File: %s", fn);
11465         proto_item_set_len(item, offset-old_offset);
11466
11467         *trunc = FALSE;
11468         return offset;
11469 }
11470
11471 static int
11472 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11473     int offset, guint16 *bcp, gboolean *trunc)
11474 {
11475         int fn_len;
11476         const char *fn;
11477         int old_offset = offset;
11478         proto_item *item = NULL;
11479         proto_tree *tree = NULL;
11480         smb_info_t *si;
11481         smb_transact2_info_t *t2i;
11482         gboolean resume_keys = FALSE;
11483
11484         si = (smb_info_t *)pinfo->private_data;
11485         if (si->sip != NULL) {
11486                 t2i = si->sip->extra_info;
11487                 if (t2i != NULL)
11488                         resume_keys = t2i->resume_keys;
11489         }
11490
11491         if(parent_tree){
11492                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11493                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11494                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11495         }
11496
11497         if (resume_keys) {
11498                 /* resume key */
11499                 CHECK_BYTE_COUNT_SUBR(4);
11500                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
11501                 COUNT_BYTES_SUBR(4);
11502         }
11503
11504         /* create time */
11505         CHECK_BYTE_COUNT_SUBR(4);
11506         offset = dissect_smb_datetime(tvb, tree, offset,
11507                 hf_smb_create_time,
11508                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
11509         *bcp -= 4;
11510
11511         /* access time */
11512         CHECK_BYTE_COUNT_SUBR(4);
11513         offset = dissect_smb_datetime(tvb, tree, offset,
11514                 hf_smb_access_time,
11515                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
11516         *bcp -= 4;
11517
11518         /* last write time */
11519         CHECK_BYTE_COUNT_SUBR(4);
11520         offset = dissect_smb_datetime(tvb, tree, offset,
11521                 hf_smb_last_write_time,
11522                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
11523         *bcp -= 4;
11524
11525         /* data size */
11526         CHECK_BYTE_COUNT_SUBR(4);
11527         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11528         COUNT_BYTES_SUBR(4);
11529
11530         /* allocation size */
11531         CHECK_BYTE_COUNT_SUBR(4);
11532         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
11533         COUNT_BYTES_SUBR(4);
11534
11535         /* File Attributes */
11536         CHECK_BYTE_COUNT_SUBR(2);
11537         offset = dissect_file_attributes(tvb, tree, offset);
11538         *bcp -= 2;
11539
11540         /* ea size */
11541         CHECK_BYTE_COUNT_SUBR(4);
11542         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
11543         COUNT_BYTES_SUBR(4);
11544
11545         /* file name len */
11546         CHECK_BYTE_COUNT_SUBR(1);
11547         fn_len = tvb_get_guint8(tvb, offset);
11548         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
11549         COUNT_BYTES_SUBR(1);
11550
11551         /* file name */
11552         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11553         CHECK_STRING_SUBR(fn);
11554         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11555                 fn);
11556         COUNT_BYTES_SUBR(fn_len);
11557         if (si->unicode)
11558                 fn_len += 2;    /* include terminating '\0' */
11559         else
11560                 fn_len++;       /* include terminating '\0' */
11561
11562         if (check_col(pinfo->cinfo, COL_INFO)) {
11563                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11564                 fn);
11565         }
11566
11567         proto_item_append_text(item, " File: %s", fn);
11568         proto_item_set_len(item, offset-old_offset);
11569
11570         *trunc = FALSE;
11571         return offset;
11572 }
11573
11574 static int
11575 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11576     int offset, guint16 *bcp, gboolean *trunc)
11577 {
11578         int fn_len;
11579         const char *fn;
11580         int old_offset = offset;
11581         proto_item *item = NULL;
11582         proto_tree *tree = NULL;
11583         smb_info_t *si;
11584         guint32 neo;
11585         int padcnt;
11586
11587         si = (smb_info_t *)pinfo->private_data;
11588
11589         if(parent_tree){
11590                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11591                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11592                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11593         }
11594
11595         /*
11596          * We assume that the presence of a next entry offset implies the
11597          * absence of a resume key, as appears to be the case for 4.3.4.6.
11598          */
11599
11600         /* next entry offset */
11601         CHECK_BYTE_COUNT_SUBR(4);
11602         neo = tvb_get_letohl(tvb, offset);
11603         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11604         COUNT_BYTES_SUBR(4);
11605
11606         /* file index */
11607         CHECK_BYTE_COUNT_SUBR(4);
11608         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11609         COUNT_BYTES_SUBR(4);
11610
11611         /* create time */
11612         CHECK_BYTE_COUNT_SUBR(8);
11613         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
11614         *bcp -= 8;
11615
11616         /* access time */
11617         CHECK_BYTE_COUNT_SUBR(8);
11618         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
11619         *bcp -= 8;
11620
11621         /* last write time */
11622         CHECK_BYTE_COUNT_SUBR(8);
11623         offset = dissect_smb_64bit_time(tvb, tree, offset,
11624                 hf_smb_last_write_time);
11625         *bcp -= 8;
11626
11627         /* last change time */
11628         CHECK_BYTE_COUNT_SUBR(8);
11629         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
11630         *bcp -= 8;
11631
11632         /* end of file */
11633         CHECK_BYTE_COUNT_SUBR(8);
11634         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11635         COUNT_BYTES_SUBR(8);
11636
11637         /* allocation size */
11638         CHECK_BYTE_COUNT_SUBR(8);
11639         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11640         COUNT_BYTES_SUBR(8);
11641
11642         /* Extended File Attributes */
11643         CHECK_BYTE_COUNT_SUBR(4);
11644         offset = dissect_file_ext_attr(tvb, tree, offset);
11645         *bcp -= 4;
11646
11647         /* file name len */
11648         CHECK_BYTE_COUNT_SUBR(4);
11649         fn_len = tvb_get_letohl(tvb, offset);
11650         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11651         COUNT_BYTES_SUBR(4);
11652
11653         /* file name */
11654         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11655         CHECK_STRING_SUBR(fn);
11656         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11657                 fn);
11658         COUNT_BYTES_SUBR(fn_len);
11659
11660         if (check_col(pinfo->cinfo, COL_INFO)) {
11661                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11662                 fn);
11663         }
11664
11665         /* skip to next structure */
11666         if(neo){
11667                 padcnt = (old_offset + neo) - offset;
11668                 if (padcnt < 0) {
11669                         /*
11670                          * XXX - this is bogus; flag it?
11671                          */
11672                         padcnt = 0;
11673                 }
11674                 if (padcnt != 0) {
11675                         CHECK_BYTE_COUNT_SUBR(padcnt);
11676                         COUNT_BYTES_SUBR(padcnt);
11677                 }
11678         }
11679
11680         proto_item_append_text(item, " File: %s", fn);
11681         proto_item_set_len(item, offset-old_offset);
11682
11683         *trunc = FALSE;
11684         return offset;
11685 }
11686
11687 static int
11688 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11689     int offset, guint16 *bcp, gboolean *trunc)
11690 {
11691         int fn_len;
11692         const char *fn;
11693         int old_offset = offset;
11694         proto_item *item = NULL;
11695         proto_tree *tree = NULL;
11696         smb_info_t *si;
11697         guint32 neo;
11698         int padcnt;
11699
11700         si = (smb_info_t *)pinfo->private_data;
11701
11702         if(parent_tree){
11703                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11704                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11705                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11706         }
11707
11708         /*
11709          * We assume that the presence of a next entry offset implies the
11710          * absence of a resume key, as appears to be the case for 4.3.4.6.
11711          */
11712
11713         /* next entry offset */
11714         CHECK_BYTE_COUNT_SUBR(4);
11715         neo = tvb_get_letohl(tvb, offset);
11716         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11717         COUNT_BYTES_SUBR(4);
11718
11719         /* file index */
11720         CHECK_BYTE_COUNT_SUBR(4);
11721         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11722         COUNT_BYTES_SUBR(4);
11723
11724         /* create time */
11725         CHECK_BYTE_COUNT_SUBR(8);
11726         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
11727         *bcp -= 8;
11728
11729         /* access time */
11730         CHECK_BYTE_COUNT_SUBR(8);
11731         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
11732         *bcp -= 8;
11733
11734         /* last write time */
11735         CHECK_BYTE_COUNT_SUBR(8);
11736         offset = dissect_smb_64bit_time(tvb, tree, offset,
11737                 hf_smb_last_write_time);
11738         *bcp -= 8;
11739
11740         /* last change time */
11741         CHECK_BYTE_COUNT_SUBR(8);
11742         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
11743         *bcp -= 8;
11744
11745         /* end of file */
11746         CHECK_BYTE_COUNT_SUBR(8);
11747         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11748         COUNT_BYTES_SUBR(8);
11749
11750         /* allocation size */
11751         CHECK_BYTE_COUNT_SUBR(8);
11752         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11753         COUNT_BYTES_SUBR(8);
11754
11755         /* Extended File Attributes */
11756         CHECK_BYTE_COUNT_SUBR(4);
11757         offset = dissect_file_ext_attr(tvb, tree, offset);
11758         *bcp -= 4;
11759
11760         /* file name len */
11761         CHECK_BYTE_COUNT_SUBR(4);
11762         fn_len = tvb_get_letohl(tvb, offset);
11763         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11764         COUNT_BYTES_SUBR(4);
11765
11766         /* ea size */
11767         CHECK_BYTE_COUNT_SUBR(4);
11768         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
11769         COUNT_BYTES_SUBR(4);
11770
11771         /* file name */
11772         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11773         CHECK_STRING_SUBR(fn);
11774         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11775                 fn);
11776         COUNT_BYTES_SUBR(fn_len);
11777
11778         if (check_col(pinfo->cinfo, COL_INFO)) {
11779                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11780                 fn);
11781         }
11782
11783         /* skip to next structure */
11784         if(neo){
11785                 padcnt = (old_offset + neo) - offset;
11786                 if (padcnt < 0) {
11787                         /*
11788                          * XXX - this is bogus; flag it?
11789                          */
11790                         padcnt = 0;
11791                 }
11792                 if (padcnt != 0) {
11793                         CHECK_BYTE_COUNT_SUBR(padcnt);
11794                         COUNT_BYTES_SUBR(padcnt);
11795                 }
11796         }
11797
11798         proto_item_append_text(item, " File: %s", fn);
11799         proto_item_set_len(item, offset-old_offset);
11800
11801         *trunc = FALSE;
11802         return offset;
11803 }
11804
11805 static int
11806 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11807     int offset, guint16 *bcp, gboolean *trunc)
11808 {
11809         int fn_len, sfn_len;
11810         const char *fn, *sfn;
11811         int old_offset = offset;
11812         proto_item *item = NULL;
11813         proto_tree *tree = NULL;
11814         smb_info_t *si;
11815         guint32 neo;
11816         int padcnt;
11817
11818         si = (smb_info_t *)pinfo->private_data;
11819
11820         if(parent_tree){
11821                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11822                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11823                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11824         }
11825
11826         /*
11827          * XXX - I have not seen any of these that contain a resume
11828          * key, even though some of the requests had the "return resume
11829          * key" flag set.
11830          */
11831
11832         /* next entry offset */
11833         CHECK_BYTE_COUNT_SUBR(4);
11834         neo = tvb_get_letohl(tvb, offset);
11835         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11836         COUNT_BYTES_SUBR(4);
11837
11838         /* file index */
11839         CHECK_BYTE_COUNT_SUBR(4);
11840         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11841         COUNT_BYTES_SUBR(4);
11842
11843         /* create time */
11844         CHECK_BYTE_COUNT_SUBR(8);
11845         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
11846         *bcp -= 8;
11847
11848         /* access time */
11849         CHECK_BYTE_COUNT_SUBR(8);
11850         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
11851         *bcp -= 8;
11852
11853         /* last write time */
11854         CHECK_BYTE_COUNT_SUBR(8);
11855         offset = dissect_smb_64bit_time(tvb, tree, offset,
11856                 hf_smb_last_write_time);
11857         *bcp -= 8;
11858
11859         /* last change time */
11860         CHECK_BYTE_COUNT_SUBR(8);
11861         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
11862         *bcp -= 8;
11863
11864         /* end of file */
11865         CHECK_BYTE_COUNT_SUBR(8);
11866         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11867         COUNT_BYTES_SUBR(8);
11868
11869         /* allocation size */
11870         CHECK_BYTE_COUNT_SUBR(8);
11871         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11872         COUNT_BYTES_SUBR(8);
11873
11874         /* Extended File Attributes */
11875         CHECK_BYTE_COUNT_SUBR(4);
11876         offset = dissect_file_ext_attr(tvb, tree, offset);
11877         *bcp -= 4;
11878
11879         /* file name len */
11880         CHECK_BYTE_COUNT_SUBR(4);
11881         fn_len = tvb_get_letohl(tvb, offset);
11882         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11883         COUNT_BYTES_SUBR(4);
11884
11885         /* ea size */
11886         CHECK_BYTE_COUNT_SUBR(4);
11887         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
11888         COUNT_BYTES_SUBR(4);
11889
11890         /* short file name len */
11891         CHECK_BYTE_COUNT_SUBR(1);
11892         sfn_len = tvb_get_guint8(tvb, offset);
11893         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
11894         COUNT_BYTES_SUBR(1);
11895
11896         /* reserved byte */
11897         CHECK_BYTE_COUNT_SUBR(1);
11898         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11899         COUNT_BYTES_SUBR(1);
11900
11901         /* short file name */
11902         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
11903         CHECK_STRING_SUBR(sfn);
11904         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
11905                 sfn);
11906         COUNT_BYTES_SUBR(24);
11907
11908         /* file name */
11909         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11910         CHECK_STRING_SUBR(fn);
11911         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11912                 fn);
11913         COUNT_BYTES_SUBR(fn_len);
11914
11915         if (check_col(pinfo->cinfo, COL_INFO)) {
11916                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11917                 fn);
11918         }
11919
11920         /* skip to next structure */
11921         if(neo){
11922                 padcnt = (old_offset + neo) - offset;
11923                 if (padcnt < 0) {
11924                         /*
11925                          * XXX - this is bogus; flag it?
11926                          */
11927                         padcnt = 0;
11928                 }
11929                 if (padcnt != 0) {
11930                         CHECK_BYTE_COUNT_SUBR(padcnt);
11931                         COUNT_BYTES_SUBR(padcnt);
11932                 }
11933         }
11934
11935         proto_item_append_text(item, " File: %s", fn);
11936         proto_item_set_len(item, offset-old_offset);
11937
11938         *trunc = FALSE;
11939         return offset;
11940 }
11941
11942 static int
11943 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11944     int offset, guint16 *bcp, gboolean *trunc)
11945 {
11946         int fn_len;
11947         const char *fn;
11948         int old_offset = offset;
11949         proto_item *item = NULL;
11950         proto_tree *tree = NULL;
11951         smb_info_t *si;
11952         guint32 neo;
11953         int padcnt;
11954
11955         si = (smb_info_t *)pinfo->private_data;
11956
11957         if(parent_tree){
11958                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11959                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11960                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11961         }
11962
11963         /*
11964          * We assume that the presence of a next entry offset implies the
11965          * absence of a resume key, as appears to be the case for 4.3.4.6.
11966          */
11967
11968         /* next entry offset */
11969         CHECK_BYTE_COUNT_SUBR(4);
11970         neo = tvb_get_letohl(tvb, offset);
11971         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11972         COUNT_BYTES_SUBR(4);
11973
11974         /* file index */
11975         CHECK_BYTE_COUNT_SUBR(4);
11976         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11977         COUNT_BYTES_SUBR(4);
11978
11979         /* file name len */
11980         CHECK_BYTE_COUNT_SUBR(4);
11981         fn_len = tvb_get_letohl(tvb, offset);
11982         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11983         COUNT_BYTES_SUBR(4);
11984
11985         /* file name */
11986         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11987         CHECK_STRING_SUBR(fn);
11988         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11989                 fn);
11990         COUNT_BYTES_SUBR(fn_len);
11991
11992         if (check_col(pinfo->cinfo, COL_INFO)) {
11993                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11994                 fn);
11995         }
11996
11997         /* skip to next structure */
11998         if(neo){
11999                 padcnt = (old_offset + neo) - offset;
12000                 if (padcnt < 0) {
12001                         /*
12002                          * XXX - this is bogus; flag it?
12003                          */
12004                         padcnt = 0;
12005                 }
12006                 if (padcnt != 0) {
12007                         CHECK_BYTE_COUNT_SUBR(padcnt);
12008                         COUNT_BYTES_SUBR(padcnt);
12009                 }
12010         }
12011
12012         proto_item_append_text(item, " File: %s", fn);
12013         proto_item_set_len(item, offset-old_offset);
12014
12015         *trunc = FALSE;
12016         return offset;
12017 }
12018
12019 static int
12020 dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
12021                 proto_tree *parent_tree _U_, int offset, guint16 *bcp,
12022                 gboolean *trunc)
12023 {
12024 /*XXX im lazy. i havnt implemented this */
12025         offset += *bcp;
12026         *bcp = 0;
12027         *trunc = FALSE;
12028         return offset;
12029 }
12030
12031 /*dissect the data block for TRANS2_FIND_FIRST2*/
12032 static int
12033 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
12034     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
12035 {
12036         smb_info_t *si;
12037
12038         if(!*bcp){
12039                 return offset;
12040         }
12041
12042         si = (smb_info_t *)pinfo->private_data;
12043         switch(si->info_level){
12044         case 1:         /*Info Standard*/
12045                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
12046                     trunc);
12047                 break;
12048         case 2:         /*Info Query EA Size*/
12049                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
12050                     trunc);
12051                 break;
12052         case 3:         /*Info Query EAs From List same as
12053                                 InfoQueryEASize*/
12054                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
12055                     trunc);
12056                 break;
12057         case 0x0101:    /*Find File Directory Info*/
12058                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
12059                     trunc);
12060                 break;
12061         case 0x0102:    /*Find File Full Directory Info*/
12062                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
12063                     trunc);
12064                 break;
12065         case 0x0103:    /*Find File Names Info*/
12066                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
12067                     trunc);
12068                 break;
12069         case 0x0104:    /*Find File Both Directory Info*/
12070                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
12071                     trunc);
12072                 break;
12073         case 0x0202:    /*Find File UNIX*/
12074                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
12075                     trunc);
12076                 break;
12077         default:        /* unknown info level */
12078                 *trunc = FALSE;
12079                 break;
12080         }
12081         return offset;
12082 }
12083
12084
12085 static int
12086 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12087 {
12088         guint32 mask;
12089         proto_item *item = NULL;
12090         proto_tree *tree = NULL;
12091
12092         mask = tvb_get_letohl(tvb, offset);
12093
12094         if(parent_tree){
12095                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
12096                         "FS Attributes: 0x%08x", mask);
12097                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
12098         }
12099
12100         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
12101                 tvb, offset, 4, mask);
12102         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
12103                 tvb, offset, 4, mask);
12104         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
12105                 tvb, offset, 4, mask);
12106         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
12107                 tvb, offset, 4, mask);
12108         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
12109                 tvb, offset, 4, mask);
12110         proto_tree_add_boolean(tree, hf_smb_fs_attr_dim,
12111                 tvb, offset, 4, mask);
12112         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
12113                 tvb, offset, 4, mask);
12114
12115         offset += 4;
12116         return offset;
12117 }
12118
12119
12120 static int
12121 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
12122 {
12123         guint32 mask;
12124         proto_item *item = NULL;
12125         proto_tree *tree = NULL;
12126
12127         mask = tvb_get_letohl(tvb, offset);
12128
12129         if(parent_tree){
12130                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
12131                         "Device Characteristics: 0x%08x", mask);
12132                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
12133         }
12134
12135         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
12136                 tvb, offset, 4, mask);
12137         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
12138                 tvb, offset, 4, mask);
12139         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
12140                 tvb, offset, 4, mask);
12141         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
12142                 tvb, offset, 4, mask);
12143         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
12144                 tvb, offset, 4, mask);
12145         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
12146                 tvb, offset, 4, mask);
12147         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
12148                 tvb, offset, 4, mask);
12149
12150         offset += 4;
12151         return offset;
12152 }
12153
12154 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
12155
12156 static const true_false_string tfs_smb_mac_access_ctrl = {
12157   "Macintosh Access Control Supported",
12158   "Macintosh Access Control Not Supported"
12159 };
12160
12161 static const true_false_string tfs_smb_mac_getset_comments = {
12162   "Macintosh Get & Set Comments Supported",
12163   "Macintosh Get & Set Comments Not Supported"
12164 };
12165
12166 static const true_false_string tfs_smb_mac_desktopdb_calls = {
12167   "Macintosh Get & Set Desktop Database Info Supported",
12168   "Macintosh Get & Set Desktop Database Info Supported"
12169 };
12170
12171 static const true_false_string tfs_smb_mac_unique_ids = {
12172   "Macintosh Unique IDs Supported",
12173   "Macintosh Unique IDs Not Supported"
12174 };
12175
12176 static const true_false_string tfs_smb_mac_streams = {
12177   "Macintosh and Streams Extensions Not Supported",
12178   "Macintosh and Streams Extensions Supported"
12179 };
12180
12181 static int
12182 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
12183     int offset, guint16 *bcp)
12184 {
12185         smb_info_t *si;
12186         int fn_len, vll, fnl;
12187         const char *fn;
12188         guint support = 0;
12189         proto_item *item = NULL;
12190         proto_tree *ti = NULL;
12191
12192         if(!*bcp){
12193                 return offset;
12194         }
12195
12196         si = (smb_info_t *)pinfo->private_data;
12197         switch(si->info_level){
12198         case 1:         /* SMB_INFO_ALLOCATION */
12199                 /* filesystem id */
12200                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12201                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
12202                 COUNT_BYTES_TRANS_SUBR(4);
12203
12204                 /* sectors per unit */
12205                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12206                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12207                 COUNT_BYTES_TRANS_SUBR(4);
12208
12209                 /* units */
12210                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12211                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
12212                 COUNT_BYTES_TRANS_SUBR(4);
12213
12214                 /* avail units */
12215                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12216                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
12217                 COUNT_BYTES_TRANS_SUBR(4);
12218
12219                 /* bytes per sector, only 16bit integer here */
12220                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
12221                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12222                 COUNT_BYTES_TRANS_SUBR(2);
12223
12224                 break;
12225         case 2:         /* SMB_INFO_VOLUME */
12226                 /* volume serial number */
12227                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12228                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
12229                 COUNT_BYTES_TRANS_SUBR(4);
12230
12231                 /* volume label length, only one byte here */
12232                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
12233                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
12234                 COUNT_BYTES_TRANS_SUBR(1);
12235
12236                 /* label */
12237                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
12238                 CHECK_STRING_TRANS_SUBR(fn);
12239                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12240                         fn);
12241                 COUNT_BYTES_TRANS_SUBR(fn_len);
12242
12243                 break;
12244         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
12245         case 1001:      /* SMB_FS_LABEL_INFORMATION */
12246                 /* volume label length */
12247                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12248                 vll = tvb_get_letohl(tvb, offset);
12249                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
12250                 COUNT_BYTES_TRANS_SUBR(4);
12251
12252                 /* label */
12253                 fn_len = vll;
12254                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12255                 CHECK_STRING_TRANS_SUBR(fn);
12256                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12257                         fn);
12258                 COUNT_BYTES_TRANS_SUBR(fn_len);
12259
12260                 break;
12261         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
12262         case 1002:      /* SMB_FS_VOLUME_INFORMATION */
12263                 /* create time */
12264                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12265                 offset = dissect_smb_64bit_time(tvb, tree, offset,
12266                         hf_smb_create_time);
12267                 *bcp -= 8;
12268
12269                 /* volume serial number */
12270                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12271                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
12272                 COUNT_BYTES_TRANS_SUBR(4);
12273
12274                 /* volume label length */
12275                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12276                 vll = tvb_get_letohl(tvb, offset);
12277                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
12278                 COUNT_BYTES_TRANS_SUBR(4);
12279
12280                 /* 2 reserved bytes */
12281                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
12282                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
12283                 COUNT_BYTES_TRANS_SUBR(2);
12284
12285                 /* label */
12286                 fn_len = vll;
12287                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12288                 CHECK_STRING_TRANS_SUBR(fn);
12289                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
12290                         fn);
12291                 COUNT_BYTES_TRANS_SUBR(fn_len);
12292
12293                 break;
12294         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
12295         case 1003:      /* SMB_FS_SIZE_INFORMATION */
12296                 /* allocation size */
12297                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12298                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12299                 COUNT_BYTES_TRANS_SUBR(8);
12300
12301                 /* free allocation units */
12302                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12303                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
12304                 COUNT_BYTES_TRANS_SUBR(8);
12305
12306                 /* sectors per unit */
12307                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12308                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12309                 COUNT_BYTES_TRANS_SUBR(4);
12310
12311                 /* bytes per sector */
12312                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12313                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
12314                 COUNT_BYTES_TRANS_SUBR(4);
12315
12316                 break;
12317         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
12318         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
12319                 /* device type */
12320                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12321                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
12322                 COUNT_BYTES_TRANS_SUBR(4);
12323
12324                 /* device characteristics */
12325                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12326                 offset = dissect_device_characteristics(tvb, tree, offset);
12327                 *bcp -= 4;
12328
12329                 break;
12330         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
12331         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
12332                 /* FS attributes */
12333                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12334                 offset = dissect_fs_attributes(tvb, tree, offset);
12335                 *bcp -= 4;
12336
12337                 /* max name len */
12338                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12339                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
12340                 COUNT_BYTES_TRANS_SUBR(4);
12341
12342                 /* fs name length */
12343                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12344                 fnl = tvb_get_letohl(tvb, offset);
12345                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
12346                 COUNT_BYTES_TRANS_SUBR(4);
12347
12348                 /* label */
12349                 fn_len = fnl;
12350                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12351                 CHECK_STRING_TRANS_SUBR(fn);
12352                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
12353                         fn);
12354                 COUNT_BYTES_TRANS_SUBR(fn_len);
12355
12356                 break;
12357         case 0x301:     /* MAC_QUERY_FS_INFO */
12358                 /* Create time */
12359                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12360                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12361                 *bcp -= 8;
12362                 /* Modify Time */
12363                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12364                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_modify_time);
12365                 *bcp -= 8;
12366                 /* Backup Time */
12367                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12368                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_backup_time);
12369                 *bcp -= 8;
12370                 /* Allocation blocks */
12371                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12372                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
12373                                     offset,
12374                                     4, TRUE);
12375                 COUNT_BYTES_TRANS_SUBR(4);
12376                 /* Allocation Block Size */
12377                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12378                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
12379                                     offset, 4, TRUE);
12380                 COUNT_BYTES_TRANS_SUBR(4);
12381                 /* Free Block Count */
12382                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12383                 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
12384                                     offset, 4, TRUE);
12385                 COUNT_BYTES_TRANS_SUBR(4);
12386                 /* Finder Info ... */
12387                 CHECK_BYTE_COUNT_TRANS_SUBR(32);
12388                 proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb,
12389                                             offset, 32,
12390                                             tvb_get_ptr(tvb, offset,32),
12391                                             "Finder Info: %s",
12392                                             tvb_format_text(tvb, offset, 32));
12393                 COUNT_BYTES_TRANS_SUBR(32);
12394                 /* Number Files */
12395                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12396                 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
12397                                     offset, 4, TRUE);
12398                 COUNT_BYTES_TRANS_SUBR(4);
12399                 /* Number of Root Directories */
12400                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12401                 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
12402                                     offset, 4, TRUE);
12403                 COUNT_BYTES_TRANS_SUBR(4);
12404                 /* Number of files */
12405                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12406                 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
12407                                     offset, 4, TRUE);
12408                 COUNT_BYTES_TRANS_SUBR(4);
12409                 /* Dir Count */
12410                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12411                 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
12412                                     offset, 4, TRUE);
12413                 COUNT_BYTES_TRANS_SUBR(4);
12414                 /* Mac Support Flags */
12415                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12416                 support = tvb_get_ntohl(tvb, offset);
12417                 item = proto_tree_add_text(tree, tvb, offset, 4,
12418                                            "Mac Support Flags: 0x%08x", support);
12419                 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
12420                 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
12421                                        tvb, offset, 4, support);
12422                 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
12423                                        tvb, offset, 4, support);
12424                 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
12425                                        tvb, offset, 4, support);
12426                 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
12427                                        tvb, offset, 4, support);
12428                 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
12429                                        tvb, offset, 4, support);
12430                 COUNT_BYTES_TRANS_SUBR(4);
12431                 break;
12432         case 1006:      /* QUERY_FS_QUOTA_INFO */
12433                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
12434                 break;
12435         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
12436                 /* allocation size */
12437                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12438                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12439                 COUNT_BYTES_TRANS_SUBR(8);
12440
12441                 /* caller free allocation units */
12442                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12443                 proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
12444                 COUNT_BYTES_TRANS_SUBR(8);
12445
12446                 /* actual free allocation units */
12447                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
12448                 proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
12449                 COUNT_BYTES_TRANS_SUBR(8);
12450
12451                 /* sectors per unit */
12452                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12453                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
12454                 COUNT_BYTES_TRANS_SUBR(4);
12455
12456                 /* bytes per sector */
12457                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
12458                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
12459                 COUNT_BYTES_TRANS_SUBR(4);
12460                 break;
12461         }
12462
12463         return offset;
12464 }
12465
12466 static int
12467 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
12468     proto_tree *parent_tree)
12469 {
12470         proto_item *item = NULL;
12471         proto_tree *tree = NULL;
12472         smb_info_t *si;
12473         smb_transact2_info_t *t2i;
12474         int count;
12475         gboolean trunc;
12476         int offset = 0;
12477         guint16 dc;
12478
12479         dc = tvb_reported_length(tvb);
12480
12481         si = (smb_info_t *)pinfo->private_data;
12482         if (si->sip != NULL)
12483                 t2i = si->sip->extra_info;
12484         else
12485                 t2i = NULL;
12486
12487         if(parent_tree){
12488                 if (t2i != NULL && t2i->subcmd != -1) {
12489                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
12490                                 "%s Data",
12491                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
12492                                         "Unknown (0x%02x)"));
12493                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
12494                 } else {
12495                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
12496                                 "Unknown Transaction2 Data");
12497                 }
12498         }
12499
12500         if (t2i == NULL) {
12501                 offset += dc;
12502                 return offset;
12503         }
12504         switch(t2i->subcmd){
12505         case 0x00:      /*TRANS2_OPEN2*/
12506                 /* XXX not implemented yet. See SNIA doc */
12507                 break;
12508         case 0x01:      /*TRANS2_FIND_FIRST2*/
12509                 /* returned data */
12510                 count = si->info_count;
12511
12512                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
12513                         col_append_fstr(pinfo->cinfo, COL_INFO,
12514                         ", Files:");
12515                 }
12516
12517                 while(count--){
12518                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
12519                                 offset, &dc, &trunc);
12520                         if (trunc)
12521                                 break;
12522                 }
12523                 break;
12524         case 0x02:      /*TRANS2_FIND_NEXT2*/
12525                 /* returned data */
12526                 count = si->info_count;
12527
12528                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
12529                         col_append_fstr(pinfo->cinfo, COL_INFO,
12530                         ", Files:");
12531                 }
12532
12533                 while(count--){
12534                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
12535                                 offset, &dc, &trunc);
12536                         if (trunc)
12537                                 break;
12538                 }
12539                 break;
12540         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
12541                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
12542                 break;
12543         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
12544                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
12545                 break;
12546         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
12547                 /* no data in this response */
12548                 break;
12549         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
12550                 /* identical to QUERY_PATH_INFO */
12551                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
12552                 break;
12553         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
12554                 /* no data in this response */
12555                 break;
12556         case 0x09:      /*TRANS2_FSCTL*/
12557                 /* XXX dont know how to dissect this one (yet)*/
12558
12559                 /*
12560                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12561                  * Extensions Version 3.0, Document Version 1.11,
12562                  * July 19, 1990" says this this contains a
12563                  * "File system specific return data block".
12564                  * (That means we may not be able to dissect it in any
12565                  * case.)
12566                  */
12567                 break;
12568         case 0x0a:      /*TRANS2_IOCTL2*/
12569                 /* XXX dont know how to dissect this one (yet)*/
12570
12571                 /*
12572                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12573                  * Extensions Version 3.0, Document Version 1.11,
12574                  * July 19, 1990" says this this contains a
12575                  * "Device/function specific return data block".
12576                  * (That means we may not be able to dissect it in any
12577                  * case.)
12578                  */
12579                 break;
12580         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
12581                 /* XXX dont know how to dissect this one (yet)*/
12582
12583                 /*
12584                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12585                  * Extensions Version 3.0, Document Version 1.11,
12586                  * July 19, 1990" says this this contains "the level
12587                  * dependent information about the changes which
12588                  * occurred".
12589                  */
12590                 break;
12591         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
12592                 /* XXX dont know how to dissect this one (yet)*/
12593
12594                 /*
12595                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12596                  * Extensions Version 3.0, Document Version 1.11,
12597                  * July 19, 1990" says this this contains "the level
12598                  * dependent information about the changes which
12599                  * occurred".
12600                  */
12601                 break;
12602         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
12603                 /* no data in this response */
12604                 break;
12605         case 0x0e:      /*TRANS2_SESSION_SETUP*/
12606                 /* XXX dont know how to dissect this one (yet)*/
12607                 break;
12608         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
12609                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
12610                 break;
12611         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
12612                 /* the SNIA spec appears to say the response has no data */
12613                 break;
12614         case -1:
12615                 /*
12616                  * We don't know what the matching request was; don't
12617                  * bother putting anything else into the tree for the data.
12618                  */
12619                 offset += dc;
12620                 dc = 0;
12621                 break;
12622         }
12623
12624         /* ooops there were data we didnt know how to process */
12625         if(dc != 0){
12626                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
12627                 offset += dc;
12628         }
12629
12630         return offset;
12631 }
12632
12633
12634 static void
12635 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
12636 {
12637         proto_item *item = NULL;
12638         proto_tree *tree = NULL;
12639         smb_info_t *si;
12640         smb_transact2_info_t *t2i;
12641         guint16 fid;
12642         int lno;
12643         int offset = 0;
12644         int pc;
12645
12646         pc = tvb_reported_length(tvb);
12647
12648         si = (smb_info_t *)pinfo->private_data;
12649         if (si->sip != NULL)
12650                 t2i = si->sip->extra_info;
12651         else
12652                 t2i = NULL;
12653
12654         if(parent_tree){
12655                 if (t2i != NULL && t2i->subcmd != -1) {
12656                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
12657                                 "%s Parameters",
12658                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
12659                                                 "Unknown (0x%02x)"));
12660                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
12661                 } else {
12662                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
12663                                 "Unknown Transaction2 Parameters");
12664                 }
12665         }
12666
12667         if (t2i == NULL) {
12668                 offset += pc;
12669                 return;
12670         }
12671         switch(t2i->subcmd){
12672         case 0x00:      /*TRANS2_OPEN2*/
12673                 /* fid */
12674                 fid = tvb_get_letohs(tvb, offset);
12675                 add_fid(tvb, pinfo, tree, offset, 2, fid);
12676                 offset += 2;
12677
12678                 /*
12679                  * XXX - Microsoft Networks SMB File Sharing Protocol
12680                  * Extensions Version 3.0, Document Version 1.11,
12681                  * July 19, 1990 says that the file attributes, create
12682                  * time (which it says is the last modification time),
12683                  * data size, granted access, file type, and IPC state
12684                  * are returned only if bit 0 is set in the open flags,
12685                  * and that the EA length is returned only if bit 3
12686                  * is set in the open flags.  Does that mean that,
12687                  * at least in that SMB dialect, those fields are not
12688                  * present in the reply parameters if the bits in
12689                  * question aren't set?
12690                  */
12691
12692                 /* File Attributes */
12693                 offset = dissect_file_attributes(tvb, tree, offset);
12694
12695                 /* create time */
12696                 offset = dissect_smb_datetime(tvb, tree, offset,
12697                         hf_smb_create_time,
12698                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
12699
12700                 /* data size */
12701                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12702                 offset += 4;
12703
12704                 /* granted access */
12705                 offset = dissect_access(tvb, tree, offset, "Granted");
12706
12707                 /* File Type */
12708                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
12709                 offset += 2;
12710
12711                 /* IPC State */
12712                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
12713
12714                 /* open_action */
12715                 offset = dissect_open_action(tvb, tree, offset);
12716
12717                 /* server unique file ID */
12718                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
12719                 offset += 4;
12720
12721                 /* ea error offset, only a 16 bit integer here */
12722                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12723                 offset += 2;
12724
12725                 /* ea length */
12726                 proto_tree_add_item(tree, hf_smb_ea_length, tvb, offset, 4, TRUE);
12727                 offset += 4;
12728
12729                 break;
12730         case 0x01:      /*TRANS2_FIND_FIRST2*/
12731                 /* Find First2 information level */
12732                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
12733
12734                 /* sid */
12735                 proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
12736                 offset += 2;
12737
12738                 /* search count */
12739                 si->info_count = tvb_get_letohs(tvb, offset);
12740                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
12741                 offset += 2;
12742
12743                 /* end of search */
12744                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
12745                 offset += 2;
12746
12747                 /* ea error offset, only a 16 bit integer here */
12748                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12749                 offset += 2;
12750
12751                 /* last name offset */
12752                 lno = tvb_get_letohs(tvb, offset);
12753                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
12754                 offset += 2;
12755
12756                 break;
12757         case 0x02:      /*TRANS2_FIND_NEXT2*/
12758                 /* search count */
12759                 si->info_count = tvb_get_letohs(tvb, offset);
12760                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
12761                 offset += 2;
12762
12763                 /* end of search */
12764                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
12765                 offset += 2;
12766
12767                 /* ea_error_offset, only a 16 bit integer here*/
12768                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12769                 offset += 2;
12770
12771                 /* last name offset */
12772                 lno = tvb_get_letohs(tvb, offset);
12773                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
12774                 offset += 2;
12775
12776                 break;
12777         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
12778                 /* no parameter block here */
12779                 break;
12780         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
12781                 /* ea_error_offset, only a 16 bit integer here*/
12782                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12783                 offset += 2;
12784
12785                 break;
12786         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
12787                 /* ea_error_offset, only a 16 bit integer here*/
12788                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12789                 offset += 2;
12790
12791                 break;
12792         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
12793                 /* ea_error_offset, only a 16 bit integer here*/
12794                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12795                 offset += 2;
12796
12797                 break;
12798         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
12799                 /* ea_error_offset, only a 16 bit integer here*/
12800                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12801                 offset += 2;
12802
12803                 break;
12804         case 0x09:      /*TRANS2_FSCTL*/
12805                 /* XXX dont know how to dissect this one (yet)*/
12806
12807                 /*
12808                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12809                  * Extensions Version 3.0, Document Version 1.11,
12810                  * July 19, 1990" says this this contains a
12811                  * "File system specific return parameter block".
12812                  * (That means we may not be able to dissect it in any
12813                  * case.)
12814                  */
12815                 break;
12816         case 0x0a:      /*TRANS2_IOCTL2*/
12817                 /* XXX dont know how to dissect this one (yet)*/
12818
12819                 /*
12820                  * XXX - "Microsoft Networks SMB File Sharing Protocol
12821                  * Extensions Version 3.0, Document Version 1.11,
12822                  * July 19, 1990" says this this contains a
12823                  * "Device/function specific return parameter block".
12824                  * (That means we may not be able to dissect it in any
12825                  * case.)
12826                  */
12827                 break;
12828         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
12829                 /* Find Notify information level */
12830                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
12831
12832                 /* Monitor handle */
12833                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
12834                 offset += 2;
12835
12836                 /* Change count */
12837                 si->info_count = tvb_get_letohs(tvb, offset);
12838                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
12839                 offset += 2;
12840
12841                 /* ea_error_offset, only a 16 bit integer here*/
12842                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12843                 offset += 2;
12844
12845                 break;
12846         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
12847                 /* Find Notify information level */
12848                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
12849
12850                 /* Change count */
12851                 si->info_count = tvb_get_letohs(tvb, offset);
12852                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
12853                 offset += 2;
12854
12855                 /* ea_error_offset, only a 16 bit integer here*/
12856                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12857                 offset += 2;
12858
12859                 break;
12860         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
12861                 /* ea error offset, only a 16 bit integer here */
12862                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12863                 offset += 2;
12864
12865                 break;
12866         case 0x0e:      /*TRANS2_SESSION_SETUP*/
12867                 /* XXX dont know how to dissect this one (yet)*/
12868                 break;
12869         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
12870                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
12871                 break;
12872         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
12873                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
12874                 break;
12875         case -1:
12876                 /*
12877                  * We don't know what the matching request was; don't
12878                  * bother putting anything else into the tree for the data.
12879                  */
12880                 offset += pc;
12881                 break;
12882         }
12883
12884         /* ooops there were data we didnt know how to process */
12885         if(offset<pc){
12886                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
12887                 offset += pc-offset;
12888         }
12889 }
12890
12891
12892 static int
12893 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
12894 {
12895         guint8 sc, wc;
12896         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
12897         smb_info_t *si;
12898         smb_transact2_info_t *t2i = NULL;
12899         guint16 bc;
12900         int padcnt;
12901         gboolean dissected_trans;
12902         fragment_data *r_fd = NULL;
12903         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
12904         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
12905         gboolean save_fragmented;
12906
12907         si = (smb_info_t *)pinfo->private_data;
12908
12909         switch(si->cmd){
12910         case SMB_COM_TRANSACTION2:
12911                 /* transaction2 */
12912                 if (si->sip != NULL) {
12913                         t2i = si->sip->extra_info;
12914                 } else
12915                         t2i = NULL;
12916                 if (t2i == NULL) {
12917                         /*
12918                          * We didn't see the matching request, so we don't
12919                          * know what type of transaction this is.
12920                          */
12921                         proto_tree_add_text(tree, tvb, 0, 0,
12922                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
12923                         if (check_col(pinfo->cinfo, COL_INFO)) {
12924                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
12925                         }
12926                 } else {
12927                         si->info_level = t2i->info_level;
12928                         if (t2i->subcmd == -1) {
12929                                 /*
12930                                  * We didn't manage to extract the subcommand
12931                                  * from the matching request (perhaps because
12932                                  * the frame was short), so we don't know what
12933                                  * type of transaction this is.
12934                                  */
12935                                 proto_tree_add_text(tree, tvb, 0, 0,
12936                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
12937                                 if (check_col(pinfo->cinfo, COL_INFO)) {
12938                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
12939                                 }
12940                         } else {
12941                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
12942                                 if (check_col(pinfo->cinfo, COL_INFO)) {
12943                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12944                                                 val_to_str(t2i->subcmd,
12945                                                         trans2_cmd_vals,
12946                                                         "<unknown (0x%02x)>"));
12947                                 }
12948                         }
12949                 }
12950                 break;
12951         }
12952
12953         WORD_COUNT;
12954
12955         /* total param count, only a 16bit integer here */
12956         tp = tvb_get_letohs(tvb, offset);
12957         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
12958         offset += 2;
12959
12960         /* total data count, only a 16 bit integer here */
12961         td = tvb_get_letohs(tvb, offset);
12962         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
12963         offset += 2;
12964
12965         /* 2 reserved bytes */
12966         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
12967         offset += 2;
12968
12969         /* param count */
12970         pc = tvb_get_letohs(tvb, offset);
12971         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
12972         offset += 2;
12973
12974         /* param offset */
12975         po = tvb_get_letohs(tvb, offset);
12976         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
12977         offset += 2;
12978
12979         /* param disp */
12980         pd = tvb_get_letohs(tvb, offset);
12981         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
12982         offset += 2;
12983
12984         /* data count */
12985         dc = tvb_get_letohs(tvb, offset);
12986         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
12987         offset += 2;
12988
12989         /* data offset */
12990         od = tvb_get_letohs(tvb, offset);
12991         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
12992         offset += 2;
12993
12994         /* data disp */
12995         dd = tvb_get_letohs(tvb, offset);
12996         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
12997         offset += 2;
12998
12999         /* setup count */
13000         sc = tvb_get_guint8(tvb, offset);
13001         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
13002         offset += 1;
13003
13004         /* reserved byte */
13005         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
13006         offset += 1;
13007
13008
13009         /* if there were any setup bytes, put them in a tvb for later */
13010         if(sc){
13011                 if((2*sc)>tvb_length_remaining(tvb, offset)){
13012                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
13013                 } else {
13014                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
13015                 }
13016                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
13017         } else {
13018                 s_tvb = NULL;
13019                 sp_tvb=NULL;
13020         }
13021         offset += 2*sc;
13022
13023
13024         BYTE_COUNT;
13025
13026
13027         /* reassembly of SMB Transaction data payload.
13028            In this section we do reassembly of both the data and parameters
13029            blocks of the SMB transaction command.
13030         */
13031         save_fragmented = pinfo->fragmented;
13032         /* do we need reassembly? */
13033         if( (td!=dc) || (tp!=pc) ){
13034                 /* oh yeah, either data or parameter section needs
13035                    reassembly
13036                 */
13037                 pinfo->fragmented = TRUE;
13038                 if(smb_trans_reassembly){
13039                         /* ...and we were told to do reassembly */
13040                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
13041                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
13042                                                              po, pc, pd, td+tp);
13043
13044                         }
13045                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
13046                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
13047                                                              od, dc, dd+tp, td+tp);
13048                         }
13049                 }
13050         }
13051
13052         /* if we got a reassembled fd structure from the reassembly routine we must
13053            create pd_tvb from it
13054         */
13055         if(r_fd){
13056                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
13057                                              r_fd->datalen);
13058                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
13059                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
13060                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
13061         }
13062
13063
13064         if(pd_tvb){
13065                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
13066                 if(tp){
13067                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
13068                 }
13069                 if(td){
13070                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
13071                 }
13072         } else {
13073                 /* It was not reassembled. Do as best as we can.
13074                  * in this case we always try to dissect the stuff if
13075                  * data and param displacement is 0. i.e. for the first
13076                  * (and maybe only) packet.
13077                  */
13078                 if( (pd==0) && (dd==0) ){
13079                         int min;
13080                         int reported_min;
13081                         min = MIN(pc,tvb_length_remaining(tvb,po));
13082                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
13083                         if(min && reported_min) {
13084                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
13085                         }
13086                         min = MIN(dc,tvb_length_remaining(tvb,od));
13087                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
13088                         if(min && reported_min) {
13089                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
13090                         }
13091                         /*
13092                          * A tvbuff containing the parameters
13093                          * and the data.
13094                          * XXX - check pc and dc as well?
13095                          */
13096                         if (tvb_length_remaining(tvb, po)){
13097                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
13098                         }
13099                 }
13100         }
13101
13102
13103
13104         /* parameters */
13105         if(po>offset){
13106                 /* We have some padding bytes.
13107                 */
13108                 padcnt = po-offset;
13109                 if (padcnt > bc)
13110                         padcnt = bc;
13111                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
13112                 COUNT_BYTES(padcnt);
13113         }
13114         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
13115                 /* TRANSACTION2 parameters*/
13116                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
13117         }
13118         COUNT_BYTES(pc);
13119
13120
13121         /* data */
13122         if(od>offset){
13123                 /* We have some initial padding bytes.
13124                 */
13125                 padcnt = od-offset;
13126                 if (padcnt > bc)
13127                         padcnt = bc;
13128                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
13129                 COUNT_BYTES(padcnt);
13130         }
13131         /*
13132          * If the data count is bigger than the count of bytes
13133          * remaining, clamp it so that the count of bytes remaining
13134          * doesn't go negative.
13135          */
13136         if (dc > bc)
13137                 dc = bc;
13138         COUNT_BYTES(dc);
13139
13140
13141
13142         /* from now on, everything is in separate tvbuffs so we dont count
13143            the bytes with COUNT_BYTES any more.
13144            neither do we reference offset any more (which by now points to the
13145            first byte AFTER this PDU */
13146
13147
13148         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
13149                 /* TRANSACTION2 parameters*/
13150                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
13151         }
13152
13153
13154         if(si->cmd==SMB_COM_TRANSACTION){
13155                 smb_transact_info_t *tri;
13156
13157                 dissected_trans = FALSE;
13158                 if (si->sip != NULL)
13159                         tri = si->sip->extra_info;
13160                 else
13161                         tri = NULL;
13162                 if (tri != NULL) {
13163                         switch(tri->subcmd){
13164
13165                         case TRANSACTION_PIPE:
13166                                 /* This function is safe to call for
13167                                    s_tvb==sp_tvb==NULL, i.e. if we don't
13168                                    know them at this point.
13169                                    It's also safe to call if "p_tvb"
13170                                    or "d_tvb" are null.
13171                                 */
13172                                 if( pd_tvb) {
13173                                         dissected_trans = dissect_pipe_smb(
13174                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
13175                                                 d_tvb, NULL, pinfo, top_tree);
13176                                 }
13177                                 break;
13178
13179                         case TRANSACTION_MAILSLOT:
13180                                 /* This one should be safe to call
13181                                    even if s_tvb and sp_tvb is NULL
13182                                 */
13183                                 if(d_tvb){
13184                                         dissected_trans = dissect_mailslot_smb(
13185                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
13186                                                 top_tree);
13187                                 }
13188                                 break;
13189                         }
13190                 }
13191                 if (!dissected_trans) {
13192                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
13193                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
13194                 }
13195         }
13196
13197
13198         if( (p_tvb==0) && (d_tvb==0) ){
13199                 if(check_col(pinfo->cinfo, COL_INFO)){
13200                         col_append_str(pinfo->cinfo, COL_INFO,
13201                                        "[transact continuation]");
13202                 }
13203         }
13204
13205         pinfo->fragmented = save_fragmented;
13206         END_OF_SMB
13207
13208         return offset;
13209 }
13210
13211
13212 static int
13213 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13214 {
13215         guint8 wc;
13216         guint16 bc;
13217
13218         WORD_COUNT;
13219
13220         /* Monitor handle */
13221         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
13222         offset += 2;
13223
13224         BYTE_COUNT;
13225
13226         END_OF_SMB
13227
13228         return offset;
13229 }
13230
13231 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
13232    END Transaction/Transaction2 Primary and secondary requests
13233    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
13234
13235
13236 static int
13237 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
13238 {
13239         guint8 wc;
13240         guint16 bc;
13241
13242         WORD_COUNT;
13243
13244         if (wc != 0) {
13245                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
13246                 offset += wc*2;
13247         }
13248
13249         BYTE_COUNT;
13250
13251         if (bc != 0) {
13252                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
13253                 offset += bc;
13254                 bc = 0;
13255         }
13256
13257         END_OF_SMB
13258
13259         return offset;
13260 }
13261
13262 typedef struct _smb_function {
13263        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13264        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13265 } smb_function;
13266
13267 static smb_function smb_dissector[256] = {
13268   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
13269   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
13270   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
13271   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
13272   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
13273   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
13274   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
13275   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
13276   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
13277   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
13278   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
13279   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
13280   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
13281   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
13282   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
13283   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
13284
13285   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
13286   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
13287   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
13288   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
13289   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
13290   /* 0x15 */  {dissect_unknown, dissect_unknown},
13291   /* 0x16 */  {dissect_unknown, dissect_unknown},
13292   /* 0x17 */  {dissect_unknown, dissect_unknown},
13293   /* 0x18 */  {dissect_unknown, dissect_unknown},
13294   /* 0x19 */  {dissect_unknown, dissect_unknown},
13295   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
13296   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
13297   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
13298   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
13299   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
13300   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
13301
13302   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
13303   /* 0x21 */  {dissect_unknown, dissect_unknown},
13304   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
13305   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
13306   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
13307   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
13308   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
13309   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
13310   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
13311   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
13312   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
13313   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
13314   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
13315   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
13316   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
13317   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
13318
13319   /* 0x30 */  {dissect_unknown, dissect_unknown},
13320   /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
13321   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
13322   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
13323   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
13324   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
13325   /* 0x36 */  {dissect_unknown, dissect_unknown},
13326   /* 0x37 */  {dissect_unknown, dissect_unknown},
13327   /* 0x38 */  {dissect_unknown, dissect_unknown},
13328   /* 0x39 */  {dissect_unknown, dissect_unknown},
13329   /* 0x3a */  {dissect_unknown, dissect_unknown},
13330   /* 0x3b */  {dissect_unknown, dissect_unknown},
13331   /* 0x3c */  {dissect_unknown, dissect_unknown},
13332   /* 0x3d */  {dissect_unknown, dissect_unknown},
13333   /* 0x3e */  {dissect_unknown, dissect_unknown},
13334   /* 0x3f */  {dissect_unknown, dissect_unknown},
13335
13336   /* 0x40 */  {dissect_unknown, dissect_unknown},
13337   /* 0x41 */  {dissect_unknown, dissect_unknown},
13338   /* 0x42 */  {dissect_unknown, dissect_unknown},
13339   /* 0x43 */  {dissect_unknown, dissect_unknown},
13340   /* 0x44 */  {dissect_unknown, dissect_unknown},
13341   /* 0x45 */  {dissect_unknown, dissect_unknown},
13342   /* 0x46 */  {dissect_unknown, dissect_unknown},
13343   /* 0x47 */  {dissect_unknown, dissect_unknown},
13344   /* 0x48 */  {dissect_unknown, dissect_unknown},
13345   /* 0x49 */  {dissect_unknown, dissect_unknown},
13346   /* 0x4a */  {dissect_unknown, dissect_unknown},
13347   /* 0x4b */  {dissect_unknown, dissect_unknown},
13348   /* 0x4c */  {dissect_unknown, dissect_unknown},
13349   /* 0x4d */  {dissect_unknown, dissect_unknown},
13350   /* 0x4e */  {dissect_unknown, dissect_unknown},
13351   /* 0x4f */  {dissect_unknown, dissect_unknown},
13352
13353   /* 0x50 */  {dissect_unknown, dissect_unknown},
13354   /* 0x51 */  {dissect_unknown, dissect_unknown},
13355   /* 0x52 */  {dissect_unknown, dissect_unknown},
13356   /* 0x53 */  {dissect_unknown, dissect_unknown},
13357   /* 0x54 */  {dissect_unknown, dissect_unknown},
13358   /* 0x55 */  {dissect_unknown, dissect_unknown},
13359   /* 0x56 */  {dissect_unknown, dissect_unknown},
13360   /* 0x57 */  {dissect_unknown, dissect_unknown},
13361   /* 0x58 */  {dissect_unknown, dissect_unknown},
13362   /* 0x59 */  {dissect_unknown, dissect_unknown},
13363   /* 0x5a */  {dissect_unknown, dissect_unknown},
13364   /* 0x5b */  {dissect_unknown, dissect_unknown},
13365   /* 0x5c */  {dissect_unknown, dissect_unknown},
13366   /* 0x5d */  {dissect_unknown, dissect_unknown},
13367   /* 0x5e */  {dissect_unknown, dissect_unknown},
13368   /* 0x5f */  {dissect_unknown, dissect_unknown},
13369
13370   /* 0x60 */  {dissect_unknown, dissect_unknown},
13371   /* 0x61 */  {dissect_unknown, dissect_unknown},
13372   /* 0x62 */  {dissect_unknown, dissect_unknown},
13373   /* 0x63 */  {dissect_unknown, dissect_unknown},
13374   /* 0x64 */  {dissect_unknown, dissect_unknown},
13375   /* 0x65 */  {dissect_unknown, dissect_unknown},
13376   /* 0x66 */  {dissect_unknown, dissect_unknown},
13377   /* 0x67 */  {dissect_unknown, dissect_unknown},
13378   /* 0x68 */  {dissect_unknown, dissect_unknown},
13379   /* 0x69 */  {dissect_unknown, dissect_unknown},
13380   /* 0x6a */  {dissect_unknown, dissect_unknown},
13381   /* 0x6b */  {dissect_unknown, dissect_unknown},
13382   /* 0x6c */  {dissect_unknown, dissect_unknown},
13383   /* 0x6d */  {dissect_unknown, dissect_unknown},
13384   /* 0x6e */  {dissect_unknown, dissect_unknown},
13385   /* 0x6f */  {dissect_unknown, dissect_unknown},
13386
13387   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
13388   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
13389   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
13390   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
13391   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
13392   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
13393   /* 0x76 */  {dissect_unknown, dissect_unknown},
13394   /* 0x77 */  {dissect_unknown, dissect_unknown},
13395   /* 0x78 */  {dissect_unknown, dissect_unknown},
13396   /* 0x79 */  {dissect_unknown, dissect_unknown},
13397   /* 0x7a */  {dissect_unknown, dissect_unknown},
13398   /* 0x7b */  {dissect_unknown, dissect_unknown},
13399   /* 0x7c */  {dissect_unknown, dissect_unknown},
13400   /* 0x7d */  {dissect_unknown, dissect_unknown},
13401   /* 0x7e */  {dissect_unknown, dissect_unknown},
13402   /* 0x7f */  {dissect_unknown, dissect_unknown},
13403
13404   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
13405   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
13406   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
13407   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
13408   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
13409   /* 0x85 */  {dissect_unknown, dissect_unknown},
13410   /* 0x86 */  {dissect_unknown, dissect_unknown},
13411   /* 0x87 */  {dissect_unknown, dissect_unknown},
13412   /* 0x88 */  {dissect_unknown, dissect_unknown},
13413   /* 0x89 */  {dissect_unknown, dissect_unknown},
13414   /* 0x8a */  {dissect_unknown, dissect_unknown},
13415   /* 0x8b */  {dissect_unknown, dissect_unknown},
13416   /* 0x8c */  {dissect_unknown, dissect_unknown},
13417   /* 0x8d */  {dissect_unknown, dissect_unknown},
13418   /* 0x8e */  {dissect_unknown, dissect_unknown},
13419   /* 0x8f */  {dissect_unknown, dissect_unknown},
13420
13421   /* 0x90 */  {dissect_unknown, dissect_unknown},
13422   /* 0x91 */  {dissect_unknown, dissect_unknown},
13423   /* 0x92 */  {dissect_unknown, dissect_unknown},
13424   /* 0x93 */  {dissect_unknown, dissect_unknown},
13425   /* 0x94 */  {dissect_unknown, dissect_unknown},
13426   /* 0x95 */  {dissect_unknown, dissect_unknown},
13427   /* 0x96 */  {dissect_unknown, dissect_unknown},
13428   /* 0x97 */  {dissect_unknown, dissect_unknown},
13429   /* 0x98 */  {dissect_unknown, dissect_unknown},
13430   /* 0x99 */  {dissect_unknown, dissect_unknown},
13431   /* 0x9a */  {dissect_unknown, dissect_unknown},
13432   /* 0x9b */  {dissect_unknown, dissect_unknown},
13433   /* 0x9c */  {dissect_unknown, dissect_unknown},
13434   /* 0x9d */  {dissect_unknown, dissect_unknown},
13435   /* 0x9e */  {dissect_unknown, dissect_unknown},
13436   /* 0x9f */  {dissect_unknown, dissect_unknown},
13437
13438   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
13439   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
13440   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
13441   /* 0xa3 */  {dissect_unknown, dissect_unknown},
13442   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
13443   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
13444   /* 0xa6 */  {dissect_unknown, dissect_unknown},
13445   /* 0xa7 */  {dissect_unknown, dissect_unknown},
13446   /* 0xa8 */  {dissect_unknown, dissect_unknown},
13447   /* 0xa9 */  {dissect_unknown, dissect_unknown},
13448   /* 0xaa */  {dissect_unknown, dissect_unknown},
13449   /* 0xab */  {dissect_unknown, dissect_unknown},
13450   /* 0xac */  {dissect_unknown, dissect_unknown},
13451   /* 0xad */  {dissect_unknown, dissect_unknown},
13452   /* 0xae */  {dissect_unknown, dissect_unknown},
13453   /* 0xaf */  {dissect_unknown, dissect_unknown},
13454
13455   /* 0xb0 */  {dissect_unknown, dissect_unknown},
13456   /* 0xb1 */  {dissect_unknown, dissect_unknown},
13457   /* 0xb2 */  {dissect_unknown, dissect_unknown},
13458   /* 0xb3 */  {dissect_unknown, dissect_unknown},
13459   /* 0xb4 */  {dissect_unknown, dissect_unknown},
13460   /* 0xb5 */  {dissect_unknown, dissect_unknown},
13461   /* 0xb6 */  {dissect_unknown, dissect_unknown},
13462   /* 0xb7 */  {dissect_unknown, dissect_unknown},
13463   /* 0xb8 */  {dissect_unknown, dissect_unknown},
13464   /* 0xb9 */  {dissect_unknown, dissect_unknown},
13465   /* 0xba */  {dissect_unknown, dissect_unknown},
13466   /* 0xbb */  {dissect_unknown, dissect_unknown},
13467   /* 0xbc */  {dissect_unknown, dissect_unknown},
13468   /* 0xbd */  {dissect_unknown, dissect_unknown},
13469   /* 0xbe */  {dissect_unknown, dissect_unknown},
13470   /* 0xbf */  {dissect_unknown, dissect_unknown},
13471
13472   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
13473   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
13474   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
13475   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
13476   /* 0xc4 */  {dissect_unknown, dissect_unknown},
13477   /* 0xc5 */  {dissect_unknown, dissect_unknown},
13478   /* 0xc6 */  {dissect_unknown, dissect_unknown},
13479   /* 0xc7 */  {dissect_unknown, dissect_unknown},
13480   /* 0xc8 */  {dissect_unknown, dissect_unknown},
13481   /* 0xc9 */  {dissect_unknown, dissect_unknown},
13482   /* 0xca */  {dissect_unknown, dissect_unknown},
13483   /* 0xcb */  {dissect_unknown, dissect_unknown},
13484   /* 0xcc */  {dissect_unknown, dissect_unknown},
13485   /* 0xcd */  {dissect_unknown, dissect_unknown},
13486   /* 0xce */  {dissect_unknown, dissect_unknown},
13487   /* 0xcf */  {dissect_unknown, dissect_unknown},
13488
13489   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
13490   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
13491   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
13492   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
13493   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
13494   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
13495   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
13496   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
13497   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
13498   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
13499   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
13500   /* 0xdb */  {dissect_unknown, dissect_unknown},
13501   /* 0xdc */  {dissect_unknown, dissect_unknown},
13502   /* 0xdd */  {dissect_unknown, dissect_unknown},
13503   /* 0xde */  {dissect_unknown, dissect_unknown},
13504   /* 0xdf */  {dissect_unknown, dissect_unknown},
13505
13506   /* 0xe0 */  {dissect_unknown, dissect_unknown},
13507   /* 0xe1 */  {dissect_unknown, dissect_unknown},
13508   /* 0xe2 */  {dissect_unknown, dissect_unknown},
13509   /* 0xe3 */  {dissect_unknown, dissect_unknown},
13510   /* 0xe4 */  {dissect_unknown, dissect_unknown},
13511   /* 0xe5 */  {dissect_unknown, dissect_unknown},
13512   /* 0xe6 */  {dissect_unknown, dissect_unknown},
13513   /* 0xe7 */  {dissect_unknown, dissect_unknown},
13514   /* 0xe8 */  {dissect_unknown, dissect_unknown},
13515   /* 0xe9 */  {dissect_unknown, dissect_unknown},
13516   /* 0xea */  {dissect_unknown, dissect_unknown},
13517   /* 0xeb */  {dissect_unknown, dissect_unknown},
13518   /* 0xec */  {dissect_unknown, dissect_unknown},
13519   /* 0xed */  {dissect_unknown, dissect_unknown},
13520   /* 0xee */  {dissect_unknown, dissect_unknown},
13521   /* 0xef */  {dissect_unknown, dissect_unknown},
13522
13523   /* 0xf0 */  {dissect_unknown, dissect_unknown},
13524   /* 0xf1 */  {dissect_unknown, dissect_unknown},
13525   /* 0xf2 */  {dissect_unknown, dissect_unknown},
13526   /* 0xf3 */  {dissect_unknown, dissect_unknown},
13527   /* 0xf4 */  {dissect_unknown, dissect_unknown},
13528   /* 0xf5 */  {dissect_unknown, dissect_unknown},
13529   /* 0xf6 */  {dissect_unknown, dissect_unknown},
13530   /* 0xf7 */  {dissect_unknown, dissect_unknown},
13531   /* 0xf8 */  {dissect_unknown, dissect_unknown},
13532   /* 0xf9 */  {dissect_unknown, dissect_unknown},
13533   /* 0xfa */  {dissect_unknown, dissect_unknown},
13534   /* 0xfb */  {dissect_unknown, dissect_unknown},
13535   /* 0xfc */  {dissect_unknown, dissect_unknown},
13536   /* 0xfd */  {dissect_unknown, dissect_unknown},
13537   /* 0xfe */  {dissect_unknown, dissect_unknown},
13538   /* 0xff */  {dissect_unknown, dissect_unknown},
13539 };
13540
13541 static int
13542 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
13543 {
13544         int old_offset = offset;
13545         smb_info_t *si;
13546
13547         si = pinfo->private_data;
13548         if(cmd!=0xff){
13549                 proto_item *cmd_item;
13550                 proto_tree *cmd_tree;
13551                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
13552
13553                 if (check_col(pinfo->cinfo, COL_INFO)) {
13554                         if(first_pdu){
13555                                 col_append_fstr(pinfo->cinfo, COL_INFO,
13556                                         "%s %s",
13557                                         decode_smb_name(cmd),
13558                                         (si->request)? "Request" : "Response");
13559                         } else {
13560                                 col_append_fstr(pinfo->cinfo, COL_INFO,
13561                                         "; %s",
13562                                         decode_smb_name(cmd));
13563                         }
13564
13565                 }
13566
13567                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
13568                         "%s %s (0x%02x)",
13569                         decode_smb_name(cmd),
13570                         (si->request)?"Request":"Response",
13571                         cmd);
13572
13573                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
13574
13575                 dissector = (si->request)?
13576                         smb_dissector[cmd].request:smb_dissector[cmd].response;
13577
13578                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
13579                 proto_item_set_len(cmd_item, offset-old_offset);
13580         }
13581         return offset;
13582 }
13583
13584
13585 /* NOTE: this value_string array will also be used to access data directly by
13586  * index instead of val_to_str() since
13587  * 1, the array will always span every value from 0x00 to 0xff and
13588  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
13589  * This means that this value_string array MUST always
13590  * 1, contain all entries 0x00 to 0xff
13591  * 2, all entries must be in order.
13592  */
13593 static const value_string smb_cmd_vals[] = {
13594   { 0x00, "Create Directory" },
13595   { 0x01, "Delete Directory" },
13596   { 0x02, "Open" },
13597   { 0x03, "Create" },
13598   { 0x04, "Close" },
13599   { 0x05, "Flush" },
13600   { 0x06, "Delete" },
13601   { 0x07, "Rename" },
13602   { 0x08, "Query Information" },
13603   { 0x09, "Set Information" },
13604   { 0x0A, "Read" },
13605   { 0x0B, "Write" },
13606   { 0x0C, "Lock Byte Range" },
13607   { 0x0D, "Unlock Byte Range" },
13608   { 0x0E, "Create Temp" },
13609   { 0x0F, "Create New" },
13610   { 0x10, "Check Directory" },
13611   { 0x11, "Process Exit" },
13612   { 0x12, "Seek" },
13613   { 0x13, "Lock And Read" },
13614   { 0x14, "Write And Unlock" },
13615   { 0x15, "unknown-0x15" },
13616   { 0x16, "unknown-0x16" },
13617   { 0x17, "unknown-0x17" },
13618   { 0x18, "unknown-0x18" },
13619   { 0x19, "unknown-0x19" },
13620   { 0x1A, "Read Raw" },
13621   { 0x1B, "Read MPX" },
13622   { 0x1C, "Read MPX Secondary" },
13623   { 0x1D, "Write Raw" },
13624   { 0x1E, "Write MPX" },
13625   { 0x1F, "Write MPX Secondary" },
13626   { 0x20, "Write Complete" },
13627   { 0x21, "unknown-0x21" },
13628   { 0x22, "Set Information2" },
13629   { 0x23, "Query Information2" },
13630   { 0x24, "Locking AndX" },
13631   { 0x25, "Transaction" },
13632   { 0x26, "Transaction Secondary" },
13633   { 0x27, "IOCTL" },
13634   { 0x28, "IOCTL Secondary" },
13635   { 0x29, "Copy" },
13636   { 0x2A, "Move" },
13637   { 0x2B, "Echo" },
13638   { 0x2C, "Write And Close" },
13639   { 0x2D, "Open AndX" },
13640   { 0x2E, "Read AndX" },
13641   { 0x2F, "Write AndX" },
13642   { 0x30, "unknown-0x30" },
13643   { 0x31, "Close And Tree Disconnect" },
13644   { 0x32, "Transaction2" },
13645   { 0x33, "Transaction2 Secondary" },
13646   { 0x34, "Find Close2" },
13647   { 0x35, "Find Notify Close" },
13648   { 0x36, "unknown-0x36" },
13649   { 0x37, "unknown-0x37" },
13650   { 0x38, "unknown-0x38" },
13651   { 0x39, "unknown-0x39" },
13652   { 0x3A, "unknown-0x3A" },
13653   { 0x3B, "unknown-0x3B" },
13654   { 0x3C, "unknown-0x3C" },
13655   { 0x3D, "unknown-0x3D" },
13656   { 0x3E, "unknown-0x3E" },
13657   { 0x3F, "unknown-0x3F" },
13658   { 0x40, "unknown-0x40" },
13659   { 0x41, "unknown-0x41" },
13660   { 0x42, "unknown-0x42" },
13661   { 0x43, "unknown-0x43" },
13662   { 0x44, "unknown-0x44" },
13663   { 0x45, "unknown-0x45" },
13664   { 0x46, "unknown-0x46" },
13665   { 0x47, "unknown-0x47" },
13666   { 0x48, "unknown-0x48" },
13667   { 0x49, "unknown-0x49" },
13668   { 0x4A, "unknown-0x4A" },
13669   { 0x4B, "unknown-0x4B" },
13670   { 0x4C, "unknown-0x4C" },
13671   { 0x4D, "unknown-0x4D" },
13672   { 0x4E, "unknown-0x4E" },
13673   { 0x4F, "unknown-0x4F" },
13674   { 0x50, "unknown-0x50" },
13675   { 0x51, "unknown-0x51" },
13676   { 0x52, "unknown-0x52" },
13677   { 0x53, "unknown-0x53" },
13678   { 0x54, "unknown-0x54" },
13679   { 0x55, "unknown-0x55" },
13680   { 0x56, "unknown-0x56" },
13681   { 0x57, "unknown-0x57" },
13682   { 0x58, "unknown-0x58" },
13683   { 0x59, "unknown-0x59" },
13684   { 0x5A, "unknown-0x5A" },
13685   { 0x5B, "unknown-0x5B" },
13686   { 0x5C, "unknown-0x5C" },
13687   { 0x5D, "unknown-0x5D" },
13688   { 0x5E, "unknown-0x5E" },
13689   { 0x5F, "unknown-0x5F" },
13690   { 0x60, "unknown-0x60" },
13691   { 0x61, "unknown-0x61" },
13692   { 0x62, "unknown-0x62" },
13693   { 0x63, "unknown-0x63" },
13694   { 0x64, "unknown-0x64" },
13695   { 0x65, "unknown-0x65" },
13696   { 0x66, "unknown-0x66" },
13697   { 0x67, "unknown-0x67" },
13698   { 0x68, "unknown-0x68" },
13699   { 0x69, "unknown-0x69" },
13700   { 0x6A, "unknown-0x6A" },
13701   { 0x6B, "unknown-0x6B" },
13702   { 0x6C, "unknown-0x6C" },
13703   { 0x6D, "unknown-0x6D" },
13704   { 0x6E, "unknown-0x6E" },
13705   { 0x6F, "unknown-0x6F" },
13706   { 0x70, "Tree Connect" },
13707   { 0x71, "Tree Disconnect" },
13708   { 0x72, "Negotiate Protocol" },
13709   { 0x73, "Session Setup AndX" },
13710   { 0x74, "Logoff AndX" },
13711   { 0x75, "Tree Connect AndX" },
13712   { 0x76, "unknown-0x76" },
13713   { 0x77, "unknown-0x77" },
13714   { 0x78, "unknown-0x78" },
13715   { 0x79, "unknown-0x79" },
13716   { 0x7A, "unknown-0x7A" },
13717   { 0x7B, "unknown-0x7B" },
13718   { 0x7C, "unknown-0x7C" },
13719   { 0x7D, "unknown-0x7D" },
13720   { 0x7E, "unknown-0x7E" },
13721   { 0x7F, "unknown-0x7F" },
13722   { 0x80, "Query Information Disk" },
13723   { 0x81, "Search" },
13724   { 0x82, "Find" },
13725   { 0x83, "Find Unique" },
13726   { 0x84, "Find Close" },
13727   { 0x85, "unknown-0x85" },
13728   { 0x86, "unknown-0x86" },
13729   { 0x87, "unknown-0x87" },
13730   { 0x88, "unknown-0x88" },
13731   { 0x89, "unknown-0x89" },
13732   { 0x8A, "unknown-0x8A" },
13733   { 0x8B, "unknown-0x8B" },
13734   { 0x8C, "unknown-0x8C" },
13735   { 0x8D, "unknown-0x8D" },
13736   { 0x8E, "unknown-0x8E" },
13737   { 0x8F, "unknown-0x8F" },
13738   { 0x90, "unknown-0x90" },
13739   { 0x91, "unknown-0x91" },
13740   { 0x92, "unknown-0x92" },
13741   { 0x93, "unknown-0x93" },
13742   { 0x94, "unknown-0x94" },
13743   { 0x95, "unknown-0x95" },
13744   { 0x96, "unknown-0x96" },
13745   { 0x97, "unknown-0x97" },
13746   { 0x98, "unknown-0x98" },
13747   { 0x99, "unknown-0x99" },
13748   { 0x9A, "unknown-0x9A" },
13749   { 0x9B, "unknown-0x9B" },
13750   { 0x9C, "unknown-0x9C" },
13751   { 0x9D, "unknown-0x9D" },
13752   { 0x9E, "unknown-0x9E" },
13753   { 0x9F, "unknown-0x9F" },
13754   { 0xA0, "NT Transact" },
13755   { 0xA1, "NT Transact Secondary" },
13756   { 0xA2, "NT Create AndX" },
13757   { 0xA3, "unknown-0xA3" },
13758   { 0xA4, "NT Cancel" },
13759   { 0xA5, "NT Rename" },
13760   { 0xA6, "unknown-0xA6" },
13761   { 0xA7, "unknown-0xA7" },
13762   { 0xA8, "unknown-0xA8" },
13763   { 0xA9, "unknown-0xA9" },
13764   { 0xAA, "unknown-0xAA" },
13765   { 0xAB, "unknown-0xAB" },
13766   { 0xAC, "unknown-0xAC" },
13767   { 0xAD, "unknown-0xAD" },
13768   { 0xAE, "unknown-0xAE" },
13769   { 0xAF, "unknown-0xAF" },
13770   { 0xB0, "unknown-0xB0" },
13771   { 0xB1, "unknown-0xB1" },
13772   { 0xB2, "unknown-0xB2" },
13773   { 0xB3, "unknown-0xB3" },
13774   { 0xB4, "unknown-0xB4" },
13775   { 0xB5, "unknown-0xB5" },
13776   { 0xB6, "unknown-0xB6" },
13777   { 0xB7, "unknown-0xB7" },
13778   { 0xB8, "unknown-0xB8" },
13779   { 0xB9, "unknown-0xB9" },
13780   { 0xBA, "unknown-0xBA" },
13781   { 0xBB, "unknown-0xBB" },
13782   { 0xBC, "unknown-0xBC" },
13783   { 0xBD, "unknown-0xBD" },
13784   { 0xBE, "unknown-0xBE" },
13785   { 0xBF, "unknown-0xBF" },
13786   { 0xC0, "Open Print File" },
13787   { 0xC1, "Write Print File" },
13788   { 0xC2, "Close Print File" },
13789   { 0xC3, "Get Print Queue" },
13790   { 0xC4, "unknown-0xC4" },
13791   { 0xC5, "unknown-0xC5" },
13792   { 0xC6, "unknown-0xC6" },
13793   { 0xC7, "unknown-0xC7" },
13794   { 0xC8, "unknown-0xC8" },
13795   { 0xC9, "unknown-0xC9" },
13796   { 0xCA, "unknown-0xCA" },
13797   { 0xCB, "unknown-0xCB" },
13798   { 0xCC, "unknown-0xCC" },
13799   { 0xCD, "unknown-0xCD" },
13800   { 0xCE, "unknown-0xCE" },
13801   { 0xCF, "unknown-0xCF" },
13802   { 0xD0, "Send Single Block Message" },
13803   { 0xD1, "Send Broadcast Message" },
13804   { 0xD2, "Forward User Name" },
13805   { 0xD3, "Cancel Forward" },
13806   { 0xD4, "Get Machine Name" },
13807   { 0xD5, "Send Start of Multi-block Message" },
13808   { 0xD6, "Send End of Multi-block Message" },
13809   { 0xD7, "Send Text of Multi-block Message" },
13810   { 0xD8, "SMBreadbulk" },
13811   { 0xD9, "SMBwritebulk" },
13812   { 0xDA, "SMBwritebulkdata" },
13813   { 0xDB, "unknown-0xDB" },
13814   { 0xDC, "unknown-0xDC" },
13815   { 0xDD, "unknown-0xDD" },
13816   { 0xDE, "unknown-0xDE" },
13817   { 0xDF, "unknown-0xDF" },
13818   { 0xE0, "unknown-0xE0" },
13819   { 0xE1, "unknown-0xE1" },
13820   { 0xE2, "unknown-0xE2" },
13821   { 0xE3, "unknown-0xE3" },
13822   { 0xE4, "unknown-0xE4" },
13823   { 0xE5, "unknown-0xE5" },
13824   { 0xE6, "unknown-0xE6" },
13825   { 0xE7, "unknown-0xE7" },
13826   { 0xE8, "unknown-0xE8" },
13827   { 0xE9, "unknown-0xE9" },
13828   { 0xEA, "unknown-0xEA" },
13829   { 0xEB, "unknown-0xEB" },
13830   { 0xEC, "unknown-0xEC" },
13831   { 0xED, "unknown-0xED" },
13832   { 0xEE, "unknown-0xEE" },
13833   { 0xEF, "unknown-0xEF" },
13834   { 0xF0, "unknown-0xF0" },
13835   { 0xF1, "unknown-0xF1" },
13836   { 0xF2, "unknown-0xF2" },
13837   { 0xF3, "unknown-0xF3" },
13838   { 0xF4, "unknown-0xF4" },
13839   { 0xF5, "unknown-0xF5" },
13840   { 0xF6, "unknown-0xF6" },
13841   { 0xF7, "unknown-0xF7" },
13842   { 0xF8, "unknown-0xF8" },
13843   { 0xF9, "unknown-0xF9" },
13844   { 0xFA, "unknown-0xFA" },
13845   { 0xFB, "unknown-0xFB" },
13846   { 0xFC, "unknown-0xFC" },
13847   { 0xFD, "unknown-0xFD" },
13848   { 0xFE, "SMBinvalid" },
13849   { 0xFF, "unknown-0xFF" },
13850   { 0x00, NULL },
13851 };
13852
13853 static char *decode_smb_name(unsigned char cmd)
13854 {
13855   return(smb_cmd_vals[cmd].strptr);
13856 }
13857
13858
13859
13860 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
13861  * Everything TVBUFFIFIED above this line
13862  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
13863
13864
13865 static void
13866 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
13867 {
13868         conv_tables_t *ct = ctarg;
13869
13870         if (ct->unmatched)
13871                 g_hash_table_destroy(ct->unmatched);
13872         if (ct->matched)
13873                 g_hash_table_destroy(ct->matched);
13874         if (ct->dcerpc_fid_to_frame)
13875                 g_hash_table_destroy(ct->dcerpc_fid_to_frame);
13876         if (ct->tid_service)
13877                 g_hash_table_destroy(ct->tid_service);
13878 }
13879
13880 static void
13881 smb_init_protocol(void)
13882 {
13883         if (smb_saved_info_key_chunk)
13884                 g_mem_chunk_destroy(smb_saved_info_key_chunk);
13885         if (smb_saved_info_chunk)
13886                 g_mem_chunk_destroy(smb_saved_info_chunk);
13887         if (smb_nt_transact_info_chunk)
13888                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
13889         if (smb_transact2_info_chunk)
13890                 g_mem_chunk_destroy(smb_transact2_info_chunk);
13891         if (smb_transact_info_chunk)
13892                 g_mem_chunk_destroy(smb_transact_info_chunk);
13893
13894         /*
13895          * Free the hash tables attached to the conversation table
13896          * structures, and then free the list of conversation table
13897          * data structures (which doesn't free the data structures
13898          * themselves; that's done by destroying the chunk from
13899          * which they were allocated).
13900          */
13901         if (conv_tables) {
13902                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
13903                 g_slist_free(conv_tables);
13904                 conv_tables = NULL;
13905         }
13906
13907         /*
13908          * Now destroy the chunk from which the conversation table
13909          * structures were allocated.
13910          */
13911         if (conv_tables_chunk)
13912                 g_mem_chunk_destroy(conv_tables_chunk);
13913
13914         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
13915             sizeof(smb_saved_info_t),
13916             smb_saved_info_init_count * sizeof(smb_saved_info_t),
13917             G_ALLOC_ONLY);
13918         smb_saved_info_key_chunk = g_mem_chunk_new("smb_saved_info_key_chunk",
13919             sizeof(smb_saved_info_key_t),
13920             smb_saved_info_init_count * sizeof(smb_saved_info_key_t),
13921             G_ALLOC_ONLY);
13922         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
13923             sizeof(smb_nt_transact_info_t),
13924             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
13925             G_ALLOC_ONLY);
13926         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
13927             sizeof(smb_transact2_info_t),
13928             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
13929             G_ALLOC_ONLY);
13930         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
13931             sizeof(smb_transact_info_t),
13932             smb_transact_info_init_count * sizeof(smb_transact_info_t),
13933             G_ALLOC_ONLY);
13934         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
13935             sizeof(conv_tables_t),
13936             conv_tables_count * sizeof(conv_tables_t),
13937             G_ALLOC_ONLY);
13938 }
13939
13940 static const value_string errcls_types[] = {
13941   { SMB_SUCCESS, "Success"},
13942   { SMB_ERRDOS, "DOS Error"},
13943   { SMB_ERRSRV, "Server Error"},
13944   { SMB_ERRHRD, "Hardware Error"},
13945   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
13946   { 0, NULL }
13947 };
13948
13949 const value_string DOS_errors[] = {
13950   {0, "Success"},
13951   {SMBE_insufficientbuffer, "Insufficient buffer"},
13952   {SMBE_badfunc, "Invalid function (or system call)"},
13953   {SMBE_badfile, "File not found (pathname error)"},
13954   {SMBE_badpath, "Directory not found"},
13955   {SMBE_nofids, "Too many open files"},
13956   {SMBE_noaccess, "Access denied"},
13957   {SMBE_badfid, "Invalid fid"},
13958   {SMBE_nomem,  "Out of memory"},
13959   {SMBE_badmem, "Invalid memory block address"},
13960   {SMBE_badenv, "Invalid environment"},
13961   {SMBE_badaccess, "Invalid open mode"},
13962   {SMBE_baddata, "Invalid data (only from ioctl call)"},
13963   {SMBE_res, "Reserved error code?"},
13964   {SMBE_baddrive, "Invalid drive"},
13965   {SMBE_remcd, "Attempt to delete current directory"},
13966   {SMBE_diffdevice, "Rename/move across different filesystems"},
13967   {SMBE_nofiles, "No more files found in file search"},
13968   {SMBE_badshare, "Share mode on file conflict with open mode"},
13969   {SMBE_lock, "Lock request conflicts with existing lock"},
13970   {SMBE_unsup, "Request unsupported, returned by Win 95"},
13971   {SMBE_nosuchshare, "Requested share does not exist"},
13972   {SMBE_filexists, "File in operation already exists"},
13973   {SMBE_cannotopen, "Cannot open the file specified"},
13974   {SMBE_unknownlevel, "Unknown info level"},
13975   {SMBE_invalidname, "Invalid name"},
13976   {SMBE_badpipe, "Named pipe invalid"},
13977   {SMBE_pipebusy, "All instances of pipe are busy"},
13978   {SMBE_pipeclosing, "Named pipe close in progress"},
13979   {SMBE_notconnected, "No process on other end of named pipe"},
13980   {SMBE_moredata, "More data to be returned"},
13981   {SMBE_baddirectory,  "Invalid directory name in a path."},
13982   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
13983   {SMBE_eas_nsup, "Extended attributes not supported"},
13984   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
13985   {SMBE_unknownipc, "Unknown IPC Operation"},
13986   {SMBE_noipc, "Don't support ipc"},
13987   {SMBE_alreadyexists, "File already exists"},
13988   {SMBE_unknownprinterdriver, "Unknown printer driver"},
13989   {SMBE_invalidprintername, "Invalid printer name"},
13990   {SMBE_printeralreadyexists, "Printer already exists"},
13991   {SMBE_invaliddatatype, "Invalid data type"},
13992   {SMBE_invalidenvironment, "Invalid environment"},
13993   {SMBE_printerdriverinuse, "Printer driver in use"},
13994   {SMBE_invalidparam, "Invalid parameter"},
13995   {SMBE_invalidformsize, "Invalid form size"},
13996   {SMBE_invalidsecuritydescriptor, "Invalid security descriptor"},
13997   {SMBE_invalidowner, "Invalid owner"},
13998   {SMBE_nomoreitems, "No more items"},
13999   {0, NULL}
14000   };
14001
14002 /* Error codes for the ERRSRV class */
14003
14004 static const value_string SRV_errors[] = {
14005   {SMBE_error, "Non specific error code"},
14006   {SMBE_badpw, "Bad password"},
14007   {SMBE_badtype, "Reserved"},
14008   {SMBE_access, "No permissions to perform the requested operation"},
14009   {SMBE_invnid, "TID invalid"},
14010   {SMBE_invnetname, "Invalid network name. Service not found"},
14011   {SMBE_invdevice, "Invalid device"},
14012   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
14013   {SMBE_qfull, "Print queue full"},
14014   {SMBE_qtoobig, "Queued item too big"},
14015   {SMBE_qeof, "EOF on print queue dump"},
14016   {SMBE_invpfid, "Invalid print file in smb_fid"},
14017   {SMBE_smbcmd, "Unrecognised command"},
14018   {SMBE_srverror, "SMB server internal error"},
14019   {SMBE_filespecs, "Fid and pathname invalid combination"},
14020   {SMBE_badlink, "Bad link in request ???"},
14021   {SMBE_badpermits, "Access specified for a file is not valid"},
14022   {SMBE_badpid, "Bad process id in request"},
14023   {SMBE_setattrmode, "Attribute mode invalid"},
14024   {SMBE_paused, "Message server paused"},
14025   {SMBE_msgoff, "Not receiving messages"},
14026   {SMBE_noroom, "No room for message"},
14027   {SMBE_rmuns, "Too many remote usernames"},
14028   {SMBE_timeout, "Operation timed out"},
14029   {SMBE_noresource, "No resources currently available for request."},
14030   {SMBE_toomanyuids, "Too many userids"},
14031   {SMBE_baduid, "Bad userid"},
14032   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
14033   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
14034   {SMBE_contMPX, "Resume MPX mode"},
14035   {SMBE_badPW, "Bad Password???"},
14036   {SMBE_nosupport, "Operation not supported"},
14037   { 0, NULL}
14038 };
14039
14040 /* Error codes for the ERRHRD class */
14041
14042 static const value_string HRD_errors[] = {
14043   {SMBE_nowrite, "Read only media"},
14044   {SMBE_badunit, "Unknown device"},
14045   {SMBE_notready, "Drive not ready"},
14046   {SMBE_badcmd, "Unknown command"},
14047   {SMBE_data, "Data (CRC) error"},
14048   {SMBE_badreq, "Bad request structure length"},
14049   {SMBE_seek, "Seek error"},
14050   {SMBE_badmedia, "Unknown media type"},
14051   {SMBE_badsector, "Sector not found"},
14052   {SMBE_nopaper, "Printer out of paper"},
14053   {SMBE_write, "Write fault"},
14054   {SMBE_read, "Read fault"},
14055   {SMBE_general, "General failure"},
14056   {SMBE_badshare, "A open conflicts with an existing open"},
14057   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
14058   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
14059   {SMBE_FCBunavail, "No FCBs are available to process request"},
14060   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
14061   {SMBE_diskfull, "Disk full???"},
14062   {0, NULL}
14063 };
14064
14065 static char *decode_smb_error(guint8 errcls, guint16 errcode)
14066 {
14067
14068   switch (errcls) {
14069
14070   case SMB_SUCCESS:
14071
14072     return("No Error");   /* No error ??? */
14073     break;
14074
14075   case SMB_ERRDOS:
14076
14077     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
14078     break;
14079
14080   case SMB_ERRSRV:
14081
14082     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
14083     break;
14084
14085   case SMB_ERRHRD:
14086
14087     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
14088     break;
14089
14090   default:
14091
14092     return("Unknown error class!");
14093
14094   }
14095
14096 }
14097
14098
14099 /* These are the MS country codes from
14100
14101         http://www.unicode.org/unicode/onlinedat/countries.html
14102
14103    For countries that share the same number, I choose to use only the
14104    name of the largest country. Apologies for this. If this offends you,
14105    here is the table to change that.
14106
14107    This also includes the code of 0 for "Default", which isn't in
14108    that list, but is in Microsoft's SDKs and the Cygnus "winnls.h"
14109    header file.  Presumably it means "don't override the setting
14110    on the user's machine".
14111
14112    Future versions of Microsoft's "winnls.h" header file might include
14113    additional codes; the current version matches the Unicode Consortium's
14114    table.
14115 */
14116 const value_string ms_country_codes[] = {
14117         {  0,   "Default"},
14118         {  1,   "USA"},
14119         {  2,   "Canada"},
14120         {  7,   "Russia"},
14121         { 20,   "Egypt"},
14122         { 27,   "South Africa"},
14123         { 30,   "Greece"},
14124         { 31,   "Netherlands"},
14125         { 32,   "Belgium"},
14126         { 33,   "France"},
14127         { 34,   "Spain"},
14128         { 36,   "Hungary"},
14129         { 39,   "Italy"},
14130         { 40,   "Romania"},
14131         { 41,   "Switzerland"},
14132         { 43,   "Austria"},
14133         { 44,   "United Kingdom"},
14134         { 45,   "Denmark"},
14135         { 46,   "Sweden"},
14136         { 47,   "Norway"},
14137         { 48,   "Poland"},
14138         { 49,   "Germany"},
14139         { 51,   "Peru"},
14140         { 52,   "Mexico"},
14141         { 54,   "Argentina"},
14142         { 55,   "Brazil"},
14143         { 56,   "Chile"},
14144         { 57,   "Colombia"},
14145         { 58,   "Venezuela"},
14146         { 60,   "Malaysia"},
14147         { 61,   "Australia"},
14148         { 62,   "Indonesia"},
14149         { 63,   "Philippines"},
14150         { 64,   "New Zealand"},
14151         { 65,   "Singapore"},
14152         { 66,   "Thailand"},
14153         { 81,   "Japan"},
14154         { 82,   "South Korea"},
14155         { 84,   "Viet Nam"},
14156         { 86,   "China"},
14157         { 90,   "Turkey"},
14158         { 91,   "India"},
14159         { 92,   "Pakistan"},
14160         {212,   "Morocco"},
14161         {213,   "Algeria"},
14162         {216,   "Tunisia"},
14163         {218,   "Libya"},
14164         {254,   "Kenya"},
14165         {263,   "Zimbabwe"},
14166         {298,   "Faroe Islands"},
14167         {351,   "Portugal"},
14168         {352,   "Luxembourg"},
14169         {353,   "Ireland"},
14170         {354,   "Iceland"},
14171         {355,   "Albania"},
14172         {358,   "Finland"},
14173         {359,   "Bulgaria"},
14174         {370,   "Lithuania"},
14175         {371,   "Latvia"},
14176         {372,   "Estonia"},
14177         {374,   "Armenia"},
14178         {375,   "Belarus"},
14179         {380,   "Ukraine"},
14180         {381,   "Serbia"},
14181         {385,   "Croatia"},
14182         {386,   "Slovenia"},
14183         {389,   "Macedonia"},
14184         {420,   "Czech Republic"},
14185         {421,   "Slovak Republic"},
14186         {501,   "Belize"},
14187         {502,   "Guatemala"},
14188         {503,   "El Salvador"},
14189         {504,   "Honduras"},
14190         {505,   "Nicaragua"},
14191         {506,   "Costa Rica"},
14192         {507,   "Panama"},
14193         {591,   "Bolivia"},
14194         {593,   "Ecuador"},
14195         {595,   "Paraguay"},
14196         {598,   "Uruguay"},
14197         {673,   "Brunei Darussalam"},
14198         {852,   "Hong Kong"},
14199         {853,   "Macau"},
14200         {886,   "Taiwan"},
14201         {960,   "Maldives"},
14202         {961,   "Lebanon"},
14203         {962,   "Jordan"},
14204         {963,   "Syria"},
14205         {964,   "Iraq"},
14206         {965,   "Kuwait"},
14207         {966,   "Saudi Arabia"},
14208         {967,   "Yemen"},
14209         {968,   "Oman"},
14210         {971,   "United Arab Emirates"},
14211         {972,   "Israel"},
14212         {973,   "Bahrain"},
14213         {974,   "Qatar"},
14214         {976,   "Mongolia"},
14215         {981,   "Iran"},
14216         {994,   "Azerbaijan"},
14217         {995,   "Georgia"},
14218         {996,   "Kyrgyzstan"},
14219
14220         {0,     NULL}
14221 };
14222
14223 /*
14224  * NT error codes.
14225  *
14226  * From
14227  *
14228  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
14229  */
14230 const value_string NT_errors[] = {
14231   { 0x00000000, "STATUS_SUCCESS" },
14232   { 0x00000000, "STATUS_WAIT_0" },
14233   { 0x00000001, "STATUS_WAIT_1" },
14234   { 0x00000002, "STATUS_WAIT_2" },
14235   { 0x00000003, "STATUS_WAIT_3" },
14236   { 0x0000003F, "STATUS_WAIT_63" },
14237   { 0x00000080, "STATUS_ABANDONED" },
14238   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
14239   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
14240   { 0x000000C0, "STATUS_USER_APC" },
14241   { 0x00000100, "STATUS_KERNEL_APC" },
14242   { 0x00000101, "STATUS_ALERTED" },
14243   { 0x00000102, "STATUS_TIMEOUT" },
14244   { 0x00000103, "STATUS_PENDING" },
14245   { 0x00000104, "STATUS_REPARSE" },
14246   { 0x00000105, "STATUS_MORE_ENTRIES" },
14247   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
14248   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
14249   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
14250   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
14251   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
14252   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
14253   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
14254   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
14255   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
14256   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
14257   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
14258   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
14259   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
14260   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
14261   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
14262   { 0x00000116, "STATUS_CRASH_DUMP" },
14263   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
14264   { 0x00000118, "STATUS_REPARSE_OBJECT" },
14265   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
14266   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
14267   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
14268   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
14269   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
14270   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
14271   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
14272   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
14273   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
14274   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
14275   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
14276   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
14277   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
14278   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
14279   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
14280   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
14281   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
14282   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
14283   { 0x40000012, "STATUS_EVENT_DONE" },
14284   { 0x40000013, "STATUS_EVENT_PENDING" },
14285   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
14286   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
14287   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
14288   { 0x40000017, "STATUS_WAS_UNLOCKED" },
14289   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
14290   { 0x40000019, "STATUS_WAS_LOCKED" },
14291   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
14292   { 0x4000001B, "STATUS_ALREADY_WIN32" },
14293   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
14294   { 0x4000001D, "STATUS_WX86_CONTINUE" },
14295   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
14296   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
14297   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
14298   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
14299   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
14300   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
14301   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
14302   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
14303   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
14304   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
14305   { 0x80000003, "STATUS_BREAKPOINT" },
14306   { 0x80000004, "STATUS_SINGLE_STEP" },
14307   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
14308   { 0x80000006, "STATUS_NO_MORE_FILES" },
14309   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
14310   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
14311   { 0x8000000B, "STATUS_NO_INHERITANCE" },
14312   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
14313   { 0x8000000D, "STATUS_PARTIAL_COPY" },
14314   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
14315   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
14316   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
14317   { 0x80000011, "STATUS_DEVICE_BUSY" },
14318   { 0x80000012, "STATUS_NO_MORE_EAS" },
14319   { 0x80000013, "STATUS_INVALID_EA_NAME" },
14320   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
14321   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
14322   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
14323   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
14324   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
14325   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
14326   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
14327   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
14328   { 0x8000001D, "STATUS_BUS_RESET" },
14329   { 0x8000001E, "STATUS_END_OF_MEDIA" },
14330   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
14331   { 0x80000020, "STATUS_MEDIA_CHECK" },
14332   { 0x80000021, "STATUS_SETMARK_DETECTED" },
14333   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
14334   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
14335   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
14336   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
14337   { 0x80000026, "STATUS_LONGJUMP" },
14338   { 0x80040111, "MAPI_E_LOGON_FAILED" },
14339   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
14340   { 0x80090301, "SEC_E_INVALID_HANDLE" },
14341   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
14342   { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
14343   { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
14344   { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
14345   { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
14346   { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
14347   { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
14348   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
14349   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
14350   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
14351   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
14352   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
14353   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
14354   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
14355   { 0xC0000008, "STATUS_INVALID_HANDLE" },
14356   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
14357   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
14358   { 0xC000000B, "STATUS_INVALID_CID" },
14359   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
14360   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
14361   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
14362   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
14363   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
14364   { 0xC0000011, "STATUS_END_OF_FILE" },
14365   { 0xC0000012, "STATUS_WRONG_VOLUME" },
14366   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
14367   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
14368   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
14369   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
14370   { 0xC0000017, "STATUS_NO_MEMORY" },
14371   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
14372   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
14373   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
14374   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
14375   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
14376   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
14377   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
14378   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
14379   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
14380   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
14381   { 0xC0000022, "STATUS_ACCESS_DENIED" },
14382   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
14383   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
14384   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
14385   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
14386   { 0xC0000027, "STATUS_UNWIND" },
14387   { 0xC0000028, "STATUS_BAD_STACK" },
14388   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
14389   { 0xC000002A, "STATUS_NOT_LOCKED" },
14390   { 0xC000002B, "STATUS_PARITY_ERROR" },
14391   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
14392   { 0xC000002D, "STATUS_NOT_COMMITTED" },
14393   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
14394   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
14395   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
14396   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
14397   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
14398   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
14399   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
14400   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
14401   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
14402   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
14403   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
14404   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
14405   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
14406   { 0xC000003C, "STATUS_DATA_OVERRUN" },
14407   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
14408   { 0xC000003E, "STATUS_DATA_ERROR" },
14409   { 0xC000003F, "STATUS_CRC_ERROR" },
14410   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
14411   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
14412   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
14413   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
14414   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
14415   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
14416   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
14417   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
14418   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
14419   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
14420   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
14421   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
14422   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
14423   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
14424   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
14425   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
14426   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
14427   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
14428   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
14429   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
14430   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
14431   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
14432   { 0xC0000056, "STATUS_DELETE_PENDING" },
14433   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
14434   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
14435   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
14436   { 0xC000005A, "STATUS_INVALID_OWNER" },
14437   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
14438   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
14439   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
14440   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
14441   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
14442   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
14443   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
14444   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
14445   { 0xC0000063, "STATUS_USER_EXISTS" },
14446   { 0xC0000064, "STATUS_NO_SUCH_USER" },
14447   { 0xC0000065, "STATUS_GROUP_EXISTS" },
14448   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
14449   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
14450   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
14451   { 0xC0000069, "STATUS_LAST_ADMIN" },
14452   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
14453   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
14454   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
14455   { 0xC000006D, "STATUS_LOGON_FAILURE" },
14456   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
14457   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
14458   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
14459   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
14460   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
14461   { 0xC0000073, "STATUS_NONE_MAPPED" },
14462   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
14463   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
14464   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
14465   { 0xC0000077, "STATUS_INVALID_ACL" },
14466   { 0xC0000078, "STATUS_INVALID_SID" },
14467   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
14468   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
14469   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
14470   { 0xC000007C, "STATUS_NO_TOKEN" },
14471   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
14472   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
14473   { 0xC000007F, "STATUS_DISK_FULL" },
14474   { 0xC0000080, "STATUS_SERVER_DISABLED" },
14475   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
14476   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
14477   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
14478   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
14479   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
14480   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
14481   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
14482   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
14483   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
14484   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
14485   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
14486   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
14487   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
14488   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
14489   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
14490   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
14491   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
14492   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
14493   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
14494   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
14495   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
14496   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
14497   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
14498   { 0xC0000098, "STATUS_FILE_INVALID" },
14499   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
14500   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
14501   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
14502   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
14503   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
14504   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
14505   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
14506   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
14507   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
14508   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
14509   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
14510   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
14511   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
14512   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
14513   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
14514   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
14515   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
14516   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
14517   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
14518   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
14519   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
14520   { 0xC00000AE, "STATUS_PIPE_BUSY" },
14521   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
14522   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
14523   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
14524   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
14525   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
14526   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
14527   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
14528   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
14529   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
14530   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
14531   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
14532   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
14533   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
14534   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
14535   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
14536   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
14537   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
14538   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
14539   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
14540   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
14541   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
14542   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
14543   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
14544   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
14545   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
14546   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
14547   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
14548   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
14549   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
14550   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
14551   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
14552   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
14553   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
14554   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
14555   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
14556   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
14557   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
14558   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
14559   { 0xC00000D5, "STATUS_FILE_RENAMED" },
14560   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
14561   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
14562   { 0xC00000D8, "STATUS_CANT_WAIT" },
14563   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
14564   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
14565   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
14566   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
14567   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
14568   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
14569   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
14570   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
14571   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
14572   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
14573   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
14574   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
14575   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
14576   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
14577   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
14578   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
14579   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
14580   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
14581   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
14582   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
14583   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
14584   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
14585   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
14586   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
14587   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
14588   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
14589   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
14590   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
14591   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
14592   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
14593   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
14594   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
14595   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
14596   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
14597   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
14598   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
14599   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
14600   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
14601   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
14602   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
14603   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
14604   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
14605   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
14606   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
14607   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
14608   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
14609   { 0xC0000107, "STATUS_FILES_OPEN" },
14610   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
14611   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
14612   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
14613   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
14614   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
14615   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
14616   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
14617   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
14618   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
14619   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
14620   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
14621   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
14622   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
14623   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
14624   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
14625   { 0xC0000117, "STATUS_NO_LDT" },
14626   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
14627   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
14628   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
14629   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
14630   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
14631   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
14632   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
14633   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
14634   { 0xC0000120, "STATUS_CANCELLED" },
14635   { 0xC0000121, "STATUS_CANNOT_DELETE" },
14636   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
14637   { 0xC0000123, "STATUS_FILE_DELETED" },
14638   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
14639   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
14640   { 0xC0000126, "STATUS_SPECIAL_USER" },
14641   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
14642   { 0xC0000128, "STATUS_FILE_CLOSED" },
14643   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
14644   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
14645   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
14646   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
14647   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
14648   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
14649   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
14650   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
14651   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
14652   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
14653   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
14654   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
14655   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
14656   { 0xC0000136, "STATUS_OPEN_FAILED" },
14657   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
14658   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
14659   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
14660   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
14661   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
14662   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
14663   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
14664   { 0xC000013E, "STATUS_LINK_FAILED" },
14665   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
14666   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
14667   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
14668   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
14669   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
14670   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
14671   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
14672   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
14673   { 0xC0000147, "STATUS_NO_PAGEFILE" },
14674   { 0xC0000148, "STATUS_INVALID_LEVEL" },
14675   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
14676   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
14677   { 0xC000014B, "STATUS_PIPE_BROKEN" },
14678   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
14679   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
14680   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
14681   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
14682   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
14683   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
14684   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
14685   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
14686   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
14687   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
14688   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
14689   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
14690   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
14691   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
14692   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
14693   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
14694   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
14695   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
14696   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
14697   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
14698   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
14699   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
14700   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
14701   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
14702   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
14703   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
14704   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
14705   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
14706   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
14707   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
14708   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
14709   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
14710   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
14711   { 0xC000016D, "STATUS_FT_ORPHANING" },
14712   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
14713   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
14714   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
14715   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
14716   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
14717   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
14718   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
14719   { 0xC0000178, "STATUS_NO_MEDIA" },
14720   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
14721   { 0xC000017B, "STATUS_INVALID_MEMBER" },
14722   { 0xC000017C, "STATUS_KEY_DELETED" },
14723   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
14724   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
14725   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
14726   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
14727   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
14728   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
14729   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
14730   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
14731   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
14732   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
14733   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
14734   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
14735   { 0xC0000189, "STATUS_TOO_LATE" },
14736   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
14737   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
14738   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
14739   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
14740   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
14741   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
14742   { 0xC0000190, "STATUS_TRUST_FAILURE" },
14743   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
14744   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
14745   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
14746   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
14747   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
14748   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
14749   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
14750   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
14751   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
14752   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
14753   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
14754   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
14755   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
14756   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
14757   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
14758   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
14759   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
14760   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
14761   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
14762   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
14763   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
14764   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
14765   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
14766   { 0xC000020D, "STATUS_CONNECTION_RESET" },
14767   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
14768   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
14769   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
14770   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
14771   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
14772   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
14773   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
14774   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
14775   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
14776   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
14777   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
14778   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
14779   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
14780   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
14781   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
14782   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
14783   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
14784   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
14785   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
14786   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
14787   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
14788   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
14789   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
14790   { 0xC0000225, "STATUS_NOT_FOUND" },
14791   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
14792   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
14793   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
14794   { 0xC0000229, "STATUS_FAIL_CHECK" },
14795   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
14796   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
14797   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
14798   { 0xC000022D, "STATUS_RETRY" },
14799   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
14800   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
14801   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
14802   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
14803   { 0xC0000232, "STATUS_INVALID_VARIANT" },
14804   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
14805   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
14806   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
14807   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
14808   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
14809   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
14810   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
14811   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
14812   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
14813   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
14814   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
14815   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
14816   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
14817   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
14818   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
14819   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
14820   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
14821   { 0xC0000244, "STATUS_AUDIT_FAILED" },
14822   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
14823   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
14824   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
14825   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
14826   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
14827   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
14828   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
14829   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
14830   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
14831   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
14832   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
14833   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
14834   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
14835   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
14836   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
14837   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
14838   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
14839   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
14840   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
14841   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
14842   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
14843   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
14844   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
14845   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
14846   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
14847   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
14848   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
14849   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
14850   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
14851   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
14852   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
14853   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
14854   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
14855   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
14856   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
14857   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
14858   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
14859   { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
14860   { 0xC0000272, "STATUS_NO_MATCH" },
14861   { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
14862   { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
14863   { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
14864   { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
14865   { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
14866   { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
14867   { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
14868   { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
14869   { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
14870   { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
14871   { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
14872   { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
14873   { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
14874   { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
14875   { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
14876   { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
14877   { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
14878   { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
14879   { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
14880   { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
14881   { 0xC000028E, "STATUS_NO_EFS" },
14882   { 0xC000028F, "STATUS_WRONG_EFS" },
14883   { 0xC0000290, "STATUS_NO_USER_KEYS" },
14884   { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
14885   { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
14886   { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
14887   { 0x40000294, "STATUS_WAKE_SYSTEM" },
14888   { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
14889   { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
14890   { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
14891   { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
14892   { 0xC0000299, "STATUS_SHARED_POLICY" },
14893   { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
14894   { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
14895   { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
14896   { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
14897   { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
14898   { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
14899   { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
14900   { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
14901   { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
14902   { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
14903   { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
14904   { 0xC00002A5, "STATUS_DS_BUSY" },
14905   { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
14906   { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
14907   { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
14908   { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
14909   { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
14910   { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
14911   { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
14912   { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
14913   { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
14914   { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
14915   { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
14916   { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
14917   { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
14918   { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
14919   { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
14920   { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
14921   { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
14922   { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
14923   { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
14924   { 0xC00002B9, "STATUS_NOINTERFACE" },
14925   { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
14926   { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
14927   { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
14928   { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
14929   { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
14930   { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
14931   { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
14932   { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
14933   { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
14934   { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
14935   { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
14936   { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
14937   { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
14938   { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
14939   { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
14940   { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
14941   { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
14942   { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
14943   { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
14944   { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
14945   { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
14946   { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
14947   { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
14948   { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
14949   { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
14950   { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
14951   { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
14952   { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
14953   { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
14954   { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
14955   { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
14956   { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
14957   { 0xC00002E1, "STATUS_DS_CANT_START" },
14958   { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
14959   { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
14960   { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
14961   { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
14962   { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
14963   { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
14964   { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
14965   { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
14966   { 0xC0009898, "STATUS_WOW_ASSERTION" },
14967   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
14968   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
14969   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
14970   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
14971   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
14972   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
14973   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
14974   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
14975   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
14976   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
14977   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
14978   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
14979   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
14980   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
14981   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
14982   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
14983   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
14984   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
14985   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
14986   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
14987   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
14988   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
14989   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
14990   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
14991   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
14992   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
14993   { 0xC002001B, "RPC_NT_CALL_FAILED" },
14994   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
14995   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
14996   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
14997   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
14998   { 0xC0020022, "RPC_NT_INVALID_TAG" },
14999   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
15000   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
15001   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
15002   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
15003   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
15004   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
15005   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
15006   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
15007   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
15008   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
15009   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
15010   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
15011   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
15012   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
15013   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
15014   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
15015   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
15016   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
15017   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
15018   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
15019   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
15020   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
15021   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
15022   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
15023   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
15024   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
15025   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
15026   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
15027   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
15028   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
15029   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
15030   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
15031   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
15032   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
15033   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
15034   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
15035   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
15036   { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
15037   { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
15038   { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
15039   { 0xC002100A, "RPC_P_SEND_FAILED" },
15040   { 0xC002100B, "RPC_P_TIMEOUT" },
15041   { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
15042   { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
15043   { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
15044   { 0xC0021015, "RPC_P_THREAD_LISTENING" },
15045   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
15046   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
15047   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
15048   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
15049   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
15050   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
15051   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
15052   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
15053   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
15054   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
15055   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
15056   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
15057   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
15058   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
15059   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
15060   { 0xC002004C, "EPT_NT_CANT_CREATE" },
15061   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
15062   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
15063   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
15064   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
15065   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
15066   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
15067   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
15068   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
15069   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
15070   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
15071   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
15072   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
15073   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
15074   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
15075   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
15076   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
15077   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
15078   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
15079   { 0,          NULL }
15080 };
15081
15082
15083
15084 static const true_false_string tfs_smb_flags_lock = {
15085         "Lock&Read, Write&Unlock are supported",
15086         "Lock&Read, Write&Unlock are not supported"
15087 };
15088 static const true_false_string tfs_smb_flags_receive_buffer = {
15089         "Receive buffer has been posted",
15090         "Receive buffer has not been posted"
15091 };
15092 static const true_false_string tfs_smb_flags_caseless = {
15093         "Path names are caseless",
15094         "Path names are case sensitive"
15095 };
15096 static const true_false_string tfs_smb_flags_canon = {
15097         "Pathnames are canonicalized",
15098         "Pathnames are not canonicalized"
15099 };
15100 static const true_false_string tfs_smb_flags_oplock = {
15101         "OpLock requested/granted",
15102         "OpLock not requested/granted"
15103 };
15104 static const true_false_string tfs_smb_flags_notify = {
15105         "Notify client on all modifications",
15106         "Notify client only on open"
15107 };
15108 static const true_false_string tfs_smb_flags_response = {
15109         "Message is a response to the client/redirector",
15110         "Message is a request to the server"
15111 };
15112
15113 static int
15114 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15115 {
15116         guint8 mask;
15117         proto_item *item = NULL;
15118         proto_tree *tree = NULL;
15119
15120         mask = tvb_get_guint8(tvb, offset);
15121
15122         if(parent_tree){
15123                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
15124                         "Flags: 0x%02x", mask);
15125                 tree = proto_item_add_subtree(item, ett_smb_flags);
15126         }
15127         proto_tree_add_boolean(tree, hf_smb_flags_response,
15128                 tvb, offset, 1, mask);
15129         proto_tree_add_boolean(tree, hf_smb_flags_notify,
15130                 tvb, offset, 1, mask);
15131         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
15132                 tvb, offset, 1, mask);
15133         proto_tree_add_boolean(tree, hf_smb_flags_canon,
15134                 tvb, offset, 1, mask);
15135         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
15136                 tvb, offset, 1, mask);
15137         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
15138                 tvb, offset, 1, mask);
15139         proto_tree_add_boolean(tree, hf_smb_flags_lock,
15140                 tvb, offset, 1, mask);
15141         offset += 1;
15142         return offset;
15143 }
15144
15145
15146
15147 static const true_false_string tfs_smb_flags2_long_names_allowed = {
15148         "Long file names are allowed in the response",
15149         "Long file names are not allowed in the response"
15150 };
15151 static const true_false_string tfs_smb_flags2_ea = {
15152         "Extended attributes are supported",
15153         "Extended attributes are not supported"
15154 };
15155 static const true_false_string tfs_smb_flags2_sec_sig = {
15156         "Security signatures are supported",
15157         "Security signatures are not supported"
15158 };
15159 static const true_false_string tfs_smb_flags2_long_names_used = {
15160         "Path names in request are long file names",
15161         "Path names in request are not long file names"
15162 };
15163 static const true_false_string tfs_smb_flags2_esn = {
15164         "Extended security negotiation is supported",
15165         "Extended security negotiation is not supported"
15166 };
15167 static const true_false_string tfs_smb_flags2_dfs = {
15168         "Resolve pathnames with Dfs",
15169         "Don't resolve pathnames with Dfs"
15170 };
15171 static const true_false_string tfs_smb_flags2_roe = {
15172         "Permit reads if execute-only",
15173         "Don't permit reads if execute-only"
15174 };
15175 static const true_false_string tfs_smb_flags2_nt_error = {
15176         "Error codes are NT error codes",
15177         "Error codes are DOS error codes"
15178 };
15179 static const true_false_string tfs_smb_flags2_string = {
15180         "Strings are Unicode",
15181         "Strings are ASCII"
15182 };
15183 static int
15184 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
15185 {
15186         guint16 mask;
15187         proto_item *item = NULL;
15188         proto_tree *tree = NULL;
15189
15190         mask = tvb_get_letohs(tvb, offset);
15191
15192         if(parent_tree){
15193                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
15194                         "Flags2: 0x%04x", mask);
15195                 tree = proto_item_add_subtree(item, ett_smb_flags2);
15196         }
15197
15198         proto_tree_add_boolean(tree, hf_smb_flags2_string,
15199                 tvb, offset, 2, mask);
15200         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
15201                 tvb, offset, 2, mask);
15202         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
15203                 tvb, offset, 2, mask);
15204         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
15205                 tvb, offset, 2, mask);
15206         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
15207                 tvb, offset, 2, mask);
15208         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
15209                 tvb, offset, 2, mask);
15210         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
15211                 tvb, offset, 2, mask);
15212         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
15213                 tvb, offset, 2, mask);
15214         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
15215                 tvb, offset, 2, mask);
15216
15217         offset += 2;
15218         return offset;
15219 }
15220
15221
15222
15223 #define SMB_FLAGS_DIRN 0x80
15224
15225
15226 static gboolean
15227 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
15228 {
15229         int offset = 0;
15230         proto_item *item = NULL, *hitem = NULL;
15231         proto_tree *tree = NULL, *htree = NULL;
15232         guint8          flags;
15233         guint16         flags2;
15234         smb_info_t      si;
15235         smb_saved_info_t *sip = NULL;
15236         smb_saved_info_key_t key;
15237         smb_saved_info_key_t *new_key;
15238         guint32 nt_status = 0;
15239         guint8 errclass = 0;
15240         guint16 errcode = 0;
15241         guint32 pid_mid;
15242         conversation_t *conversation;
15243         nstime_t ns;
15244
15245         top_tree=parent_tree;
15246
15247         /* must check that this really is a smb packet */
15248         if (!tvb_bytes_exist(tvb, 0, 4))
15249                 return FALSE;
15250
15251         if( (tvb_get_guint8(tvb, 0) != 0xff)
15252             || (tvb_get_guint8(tvb, 1) != 'S')
15253             || (tvb_get_guint8(tvb, 2) != 'M')
15254             || (tvb_get_guint8(tvb, 3) != 'B') ){
15255                 return FALSE;
15256         }
15257
15258         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
15259                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
15260         }
15261         if (check_col(pinfo->cinfo, COL_INFO)){
15262                 col_clear(pinfo->cinfo, COL_INFO);
15263         }
15264
15265         /* start off using the local variable, we will allocate a new one if we
15266            need to*/
15267         si.cmd = tvb_get_guint8(tvb, offset+4);
15268         flags = tvb_get_guint8(tvb, offset+9);
15269         si.request = !(flags&SMB_FLAGS_DIRN);
15270         flags2 = tvb_get_letohs(tvb, offset+10);
15271         if(flags2 & 0x8000){
15272                 si.unicode = TRUE; /* Mark them as Unicode */
15273         } else {
15274                 si.unicode = FALSE;
15275         }
15276         si.tid = tvb_get_letohs(tvb, offset+24);
15277         si.pid = tvb_get_letohs(tvb, offset+26);
15278         si.uid = tvb_get_letohs(tvb, offset+28);
15279         si.mid = tvb_get_letohs(tvb, offset+30);
15280         pid_mid = (si.pid << 16) | si.mid;
15281         si.info_level = -1;
15282         si.info_count = -1;
15283
15284         if (parent_tree) {
15285                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
15286                         -1, FALSE);
15287                 tree = proto_item_add_subtree(item, ett_smb);
15288
15289                 hitem = proto_tree_add_text(tree, tvb, offset, 32,
15290                         "SMB Header");
15291
15292                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
15293         }
15294
15295         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
15296         offset += 4;  /* Skip the marker */
15297
15298         /* find which conversation we are part of and get the tables for that
15299            conversation*/
15300         conversation = find_conversation(&pinfo->src, &pinfo->dst,
15301                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
15302         if(!conversation){
15303                 /* OK this is a new conversation so lets create it */
15304                 conversation = conversation_new(&pinfo->src, &pinfo->dst,
15305                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
15306         }
15307         /* see if we already have the smb data for this conversation */
15308         si.ct=conversation_get_proto_data(conversation, proto_smb);
15309         if(!si.ct){
15310                 /* No, not yet. create it and attach it to the conversation */
15311                 si.ct = g_mem_chunk_alloc(conv_tables_chunk);
15312                 conv_tables = g_slist_prepend(conv_tables, si.ct);
15313                 si.ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
15314                         smb_saved_info_equal_matched);
15315                 si.ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
15316                         smb_saved_info_equal_unmatched);
15317                 si.ct->dcerpc_fid_to_frame=g_hash_table_new(
15318                         smb_saved_info_hash_unmatched,
15319                         smb_saved_info_equal_unmatched);
15320                 si.ct->tid_service=g_hash_table_new(
15321                         smb_saved_info_hash_unmatched,
15322                         smb_saved_info_equal_unmatched);
15323                 conversation_add_proto_data(conversation, proto_smb, si.ct);
15324         }
15325
15326         if( (si.request)
15327             &&  (si.mid==0)
15328             &&  (si.uid==0)
15329             &&  (si.pid==0)
15330             &&  (si.tid==0) ){
15331                 /* this is a broadcast SMB packet, there will not be a reply.
15332                    We dont need to do anything
15333                 */
15334                 si.unidir = TRUE;
15335         } else if( (si.cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
15336                    ||(si.cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
15337                    ||(si.cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
15338                    ||(si.cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
15339                 /* Ok, we got a special request type. This request is either
15340                    an NT Cancel or a continuation relative to a real request
15341                    in an earlier packet.  In either case, we don't expect any
15342                    responses to this packet.  For continuations, any later
15343                    responses we see really just belong to the original request.
15344                    Anyway, we want to remember this packet somehow and
15345                    remember which original request it is associated with so
15346                    we can say nice things such as "This is a Cancellation to
15347                    the request in frame x", but we don't want the
15348                    request/response matching to get messed up.
15349
15350                    The only thing we do in this case is trying to find which original
15351                    request we match with and insert an entry for this "special"
15352                    request for later reference. We continue to reference the original
15353                    requests smb_saved_info_t but we dont touch it or change anything
15354                    in it.
15355                 */
15356
15357                 si.unidir = TRUE;  /*we dont expect an answer to this one*/
15358
15359                 if(!pinfo->fd->flags.visited){
15360                         /* try to find which original call we match and if we
15361                            find it add us to the matched table. Dont touch
15362                            anything else since we dont want this one to mess
15363                            up the request/response matching. We still consider
15364                            the initial call the real request and this is only
15365                            some sort of continuation.
15366                         */
15367                         /* we only check the unmatched table and assume that the
15368                            last seen MID matching ours is the right one.
15369                            This can fail but is better than nothing
15370                         */
15371                         sip=g_hash_table_lookup(si.ct->unmatched, (void *)pid_mid);
15372                         if(sip!=NULL){
15373                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15374                                 new_key->frame = pinfo->fd->num;
15375                                 new_key->pid_mid = pid_mid;
15376                                 g_hash_table_insert(si.ct->matched, new_key,
15377                                     sip);
15378                         }
15379                 } else {
15380                         /* we have seen this packet before; check the
15381                            matching table
15382                         */
15383                         key.frame = pinfo->fd->num;
15384                         key.pid_mid = pid_mid;
15385                         sip=g_hash_table_lookup(si.ct->matched, &key);
15386                         if(sip==NULL){
15387                         /*
15388                           We didn't find it.
15389                           Too bad, unfortunately there is not really much we can
15390                           do now since this means that we never saw the initial
15391                           request.
15392                          */
15393                         }
15394                 }
15395
15396
15397                 if(sip && sip->frame_req){
15398                         switch(si.cmd){
15399                         case SMB_COM_NT_CANCEL:
15400                                 proto_tree_add_uint(htree, hf_smb_cancel_to,
15401                                                     tvb, 0, 0, sip->frame_req);
15402                                 break;
15403                         case SMB_COM_TRANSACTION_SECONDARY:
15404                         case SMB_COM_TRANSACTION2_SECONDARY:
15405                         case SMB_COM_NT_TRANSACT_SECONDARY:
15406                                 proto_tree_add_uint(htree, hf_smb_continuation_to,
15407                                                     tvb, 0, 0, sip->frame_req);
15408                                 break;
15409                         }
15410                 } else {
15411                         switch(si.cmd){
15412                         case SMB_COM_NT_CANCEL:
15413                                 proto_tree_add_text(htree, tvb, 0, 0,
15414                                                     "Cancellation to: <unknown frame>");
15415                                 break;
15416                         case SMB_COM_TRANSACTION_SECONDARY:
15417                         case SMB_COM_TRANSACTION2_SECONDARY:
15418                         case SMB_COM_NT_TRANSACT_SECONDARY:
15419                                 proto_tree_add_text(htree, tvb, 0, 0,
15420                                                     "Continuation to: <unknown frame>");
15421                                 break;
15422                         }
15423                 }
15424         } else { /* normal bidirectional request or response */
15425                 si.unidir = FALSE;
15426
15427                 if(!pinfo->fd->flags.visited){
15428                         /* first see if we find an unmatched smb "equal" to
15429                            the current one
15430                         */
15431                         sip=g_hash_table_lookup(si.ct->unmatched, (void *)pid_mid);
15432                         if(sip!=NULL){
15433                                 gboolean cmd_match=FALSE;
15434
15435                                 /*
15436                                  * Make sure the SMB we found was the
15437                                  * same command, or a different command
15438                                  * that's another valid type of reply
15439                                  * to that command.
15440                                  */
15441                                 if(si.cmd==sip->cmd){
15442                                         cmd_match=TRUE;
15443                                 }
15444                                 else if(si.cmd==SMB_COM_NT_CANCEL){
15445                                         cmd_match=TRUE;
15446                                 }
15447                                 else if((si.cmd==SMB_COM_TRANSACTION_SECONDARY)
15448                                      && (sip->cmd==SMB_COM_TRANSACTION)){
15449                                         cmd_match=TRUE;
15450                                 }
15451                                 else if((si.cmd==SMB_COM_TRANSACTION2_SECONDARY)
15452                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
15453                                         cmd_match=TRUE;
15454                                 }
15455                                 else if((si.cmd==SMB_COM_NT_TRANSACT_SECONDARY)
15456                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
15457                                         cmd_match=TRUE;
15458                                 }
15459
15460                                 if( (si.request) || (!cmd_match) ) {
15461                                         /* If we are processing an SMB request but there was already
15462                                            another "identical" smb resuest we had not matched yet.
15463                                            This must mean that either we have a retransmission or that the
15464                                            response to the previous one was lost and the client has reused
15465                                            the MID for this conversation. In either case it's not much more
15466                                            we can do than forget the old request and concentrate on the
15467                                            present one instead.
15468
15469                                            We also do this cleanup if we see that the cmd in the original
15470                                            request in sip->cmd is not compatible with the current cmd.
15471                                            This is to prevent matching errors such as if there were two
15472                                            SMBs of different cmds but with identical MID and PID values and
15473                                            if ethereal lost the first reply and the second request.
15474                                         */
15475                                         g_hash_table_remove(si.ct->unmatched, (void *)pid_mid);
15476                                         sip=NULL; /* XXX should free it as well */
15477                                 } else {
15478                                         /* we have found a response to some request we have seen earlier.
15479                                            What we do now depends on whether this is the first response
15480                                            to that request we see (id frame_res==0) or not.
15481                                         */
15482                                         if(sip->frame_res==0){
15483                                                 /* ok it is the first response we have seen to this packet */
15484                                                 sip->frame_res = pinfo->fd->num;
15485                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15486                                                 new_key->frame = sip->frame_res;
15487                                                 new_key->pid_mid = pid_mid;
15488                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
15489                                         } else {
15490                                                 /* we have already seen another response to this one, but
15491                                                    register it anyway so we see which request it matches
15492                                                 */
15493                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15494                                                 new_key->frame = pinfo->fd->num;
15495                                                 new_key->pid_mid = pid_mid;
15496                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
15497                                         }
15498                                 }
15499                         }
15500                         if(si.request){
15501                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
15502                                 sip->frame_req = pinfo->fd->num;
15503                                 sip->frame_res = 0;
15504                                 sip->req_time.secs=pinfo->fd->abs_secs;
15505                                 sip->req_time.nsecs=pinfo->fd->abs_usecs*1000;
15506                                 sip->flags = 0;
15507                                 if(g_hash_table_lookup(si.ct->tid_service, (void *)si.tid)
15508                                     == (void *)TID_IPC) {
15509                                         sip->flags |= SMB_SIF_TID_IS_IPC;
15510                                 }
15511                                 sip->cmd = si.cmd;
15512                                 sip->extra_info = NULL;
15513                                 g_hash_table_insert(si.ct->unmatched, (void *)pid_mid, sip);
15514                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
15515                                 new_key->frame = sip->frame_req;
15516                                 new_key->pid_mid = pid_mid;
15517                                 g_hash_table_insert(si.ct->matched, new_key, sip);
15518                         }
15519                 } else {
15520                         /* we have seen this packet before; check the
15521                            matching table.
15522                            If we haven't yet seen the reply, we won't
15523                            find the info for it; we don't need it, as
15524                            we only use it to save information, and, as
15525                            we've seen this packet before, we've already
15526                            saved the information.
15527                         */
15528                         key.frame = pinfo->fd->num;
15529                         key.pid_mid = pid_mid;
15530                         sip=g_hash_table_lookup(si.ct->matched, &key);
15531                 }
15532         }
15533
15534         /*
15535          * Pass the "sip" on to subdissectors through "si".
15536          */
15537         si.sip = sip;
15538
15539         if (sip != NULL) {
15540                 /*
15541                  * Put in fields for the frame number of the frame to which
15542                  * this is a response or the frame with the response to this
15543                  * frame - if we know the frame number (i.e., it's not 0).
15544                  */
15545                 if(si.request){
15546                         if (sip->frame_res != 0)
15547                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
15548                 } else {
15549                         if (sip->frame_req != 0) {
15550                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
15551                                 ns.secs = pinfo->fd->abs_secs - sip->req_time.secs;
15552                                 ns.nsecs = pinfo->fd->abs_usecs*1000 - sip->req_time.nsecs;
15553                                 if(ns.nsecs<0){
15554                                         ns.nsecs+=1000000000;
15555                                         ns.secs--;
15556                                 }
15557                                 proto_tree_add_time(htree, hf_smb_time, tvb,
15558                                     0, 0, &ns);
15559                         }
15560                 }
15561         }
15562
15563         /* smb command */
15564         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);
15565         offset += 1;
15566
15567         if(flags2 & 0x4000){
15568                 /* handle NT 32 bit error code */
15569
15570                 nt_status = tvb_get_letohl(tvb, offset);
15571
15572                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
15573                         TRUE);
15574                 offset += 4;
15575
15576         } else {
15577                 /* handle DOS error code & class */
15578                 errclass = tvb_get_guint8(tvb, offset);
15579                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
15580                         errclass);
15581                 offset += 1;
15582
15583                 /* reserved byte */
15584                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
15585                 offset += 1;
15586
15587                 /* error code */
15588                 /* XXX - the type of this field depends on the value of
15589                  * "errcls", so there is isn't a single value_string array
15590                  * fo it, so there can't be a single field for it.
15591                  */
15592                 errcode = tvb_get_letohs(tvb, offset);
15593                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
15594                         offset, 2, errcode, "Error Code: %s",
15595                         decode_smb_error(errclass, errcode));
15596                 offset += 2;
15597         }
15598
15599         /* flags */
15600         offset = dissect_smb_flags(tvb, htree, offset);
15601
15602         /* flags2 */
15603         offset = dissect_smb_flags2(tvb, htree, offset);
15604
15605         /*
15606          * The document at
15607          *
15608          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
15609          *
15610          * (a text version of "Microsoft Networks SMB FILE SHARING
15611          * PROTOCOL, Document Version 6.0p") says that:
15612          *
15613          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
15614          *      the "High Part of PID";
15615          *
15616          *      the next four bytes are reserved;
15617          *
15618          *      the next four bytes are, for SMB-over-IPX (with no
15619          *      NetBIOS involved) two bytes of Session ID and two bytes
15620          *      of SequenceNumber.
15621          *
15622          * If we ever implement SMB-over-IPX (which I suspect goes over
15623          * IPX sockets 0x0550, 0x0552, and maybe 0x0554, as per the
15624          * document in question), we'd probably want to have some way
15625          * to determine whether this is SMB-over-IPX or not (which could
15626          * be done by adding a PT_IPXSOCKET port type, having the
15627          * IPX dissector set "pinfo->srcport" and "pinfo->destport",
15628          * and having the SMB dissector check for a port type of
15629          * PT_IPXSOCKET and for "pinfo->match_port" being either
15630          * IPX_SOCKET_NWLINK_SMB_SERVER or IPX_SOCKET_NWLINK_SMB_REDIR
15631          * or, if it also uses 0x0554, IPX_SOCKET_NWLINK_SMB_MESSENGER).
15632          */
15633
15634         /* 12 reserved bytes */
15635         proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 12, TRUE);
15636         offset += 12;
15637
15638         /* TID */
15639         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si.tid);
15640         offset += 2;
15641
15642         /* PID */
15643         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si.pid);
15644         offset += 2;
15645
15646         /* UID */
15647         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si.uid);
15648         offset += 2;
15649
15650         /* MID */
15651         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si.mid);
15652         offset += 2;
15653
15654         pinfo->private_data = &si;
15655         dissect_smb_command(tvb, pinfo, offset, tree, si.cmd, TRUE);
15656
15657         /* Append error info from this packet to info string. */
15658         if (!si.request && check_col(pinfo->cinfo, COL_INFO)) {
15659                 if (flags2 & 0x4000) {
15660                         /*
15661                          * The status is an NT status code; was there
15662                          * an error?
15663                          */
15664                         if (nt_status != 0) {
15665                                 /*
15666                                  * Yes.
15667                                  */
15668                                 col_append_fstr(
15669                                         pinfo->cinfo, COL_INFO, ", Error: %s",
15670                                         val_to_str(nt_status, NT_errors,
15671                                             "Unknown (0x%08X)"));
15672                         }
15673                 } else {
15674                         /*
15675                          * The status is a DOS error class and code; was
15676                          * there an error?
15677                          */
15678                         if (errclass != SMB_SUCCESS) {
15679                                 /*
15680                                  * Yes.
15681                                  */
15682                                 col_append_fstr(
15683                                         pinfo->cinfo, COL_INFO, ", Error: %s",
15684                                         decode_smb_error(errclass, errcode));
15685                         }
15686                 }
15687         }
15688
15689         return TRUE;
15690 }
15691
15692 void
15693 proto_register_smb(void)
15694 {
15695         static hf_register_info hf[] = {
15696         { &hf_smb_cmd,
15697                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
15698                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
15699
15700         { &hf_smb_word_count,
15701                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
15702                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
15703
15704         { &hf_smb_byte_count,
15705                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
15706                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
15707
15708         { &hf_smb_response_to,
15709                 { "Response to", "smb.response_to", FT_UINT32, BASE_DEC,
15710                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
15711
15712         { &hf_smb_time,
15713                 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
15714                 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
15715
15716         { &hf_smb_response_in,
15717                 { "Response in", "smb.response_in", FT_UINT32, BASE_DEC,
15718                 NULL, 0, "The response to this packet is in this packet", HFILL }},
15719
15720         { &hf_smb_continuation_to,
15721                 { "Continuation to", "smb.continuation_to", FT_UINT32, BASE_DEC,
15722                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
15723
15724         { &hf_smb_nt_status,
15725                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
15726                 VALS(NT_errors), 0, "NT Status code", HFILL }},
15727
15728         { &hf_smb_error_class,
15729                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
15730                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
15731
15732         { &hf_smb_error_code,
15733                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
15734                 NULL, 0, "DOS Error Code", HFILL }},
15735
15736         { &hf_smb_reserved,
15737                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
15738                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
15739
15740         { &hf_smb_pid,
15741                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
15742                 NULL, 0, "Process ID", HFILL }},
15743
15744         { &hf_smb_tid,
15745                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
15746                 NULL, 0, "Tree ID", HFILL }},
15747
15748         { &hf_smb_uid,
15749                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
15750                 NULL, 0, "User ID", HFILL }},
15751
15752         { &hf_smb_mid,
15753                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
15754                 NULL, 0, "Multiplex ID", HFILL }},
15755
15756         { &hf_smb_flags_lock,
15757                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
15758                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
15759
15760         { &hf_smb_flags_receive_buffer,
15761                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
15762                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
15763
15764         { &hf_smb_flags_caseless,
15765                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
15766                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
15767
15768         { &hf_smb_flags_canon,
15769                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
15770                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
15771
15772         { &hf_smb_flags_oplock,
15773                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
15774                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
15775
15776         { &hf_smb_flags_notify,
15777                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
15778                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
15779
15780         { &hf_smb_flags_response,
15781                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
15782                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
15783
15784         { &hf_smb_flags2_long_names_allowed,
15785                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
15786                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
15787
15788         { &hf_smb_flags2_ea,
15789                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
15790                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
15791
15792         { &hf_smb_flags2_sec_sig,
15793                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
15794                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
15795
15796         { &hf_smb_flags2_long_names_used,
15797                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
15798                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
15799
15800         { &hf_smb_flags2_esn,
15801                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
15802                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
15803
15804         { &hf_smb_flags2_dfs,
15805                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
15806                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
15807
15808         { &hf_smb_flags2_roe,
15809                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
15810                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
15811
15812         { &hf_smb_flags2_nt_error,
15813                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
15814                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
15815
15816         { &hf_smb_flags2_string,
15817                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
15818                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
15819
15820         { &hf_smb_buffer_format,
15821                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
15822                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
15823
15824         { &hf_smb_dialect_name,
15825                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
15826                 NULL, 0, "Name of dialect", HFILL }},
15827
15828         { &hf_smb_dialect_index,
15829                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
15830                 NULL, 0, "Index of selected dialect", HFILL }},
15831
15832         { &hf_smb_max_trans_buf_size,
15833                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
15834                 NULL, 0, "Maximum transmit buffer size", HFILL }},
15835
15836         { &hf_smb_max_mpx_count,
15837                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
15838                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
15839
15840         { &hf_smb_max_vcs_num,
15841                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
15842                 NULL, 0, "Maximum VCs between client and server", HFILL }},
15843
15844         { &hf_smb_session_key,
15845                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
15846                 NULL, 0, "Unique token identifying this session", HFILL }},
15847
15848         { &hf_smb_server_timezone,
15849                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
15850                 NULL, 0, "Current timezone at server.", HFILL }},
15851
15852         { &hf_smb_encryption_key_length,
15853                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
15854                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
15855
15856         { &hf_smb_encryption_key,
15857                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
15858                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
15859
15860         { &hf_smb_primary_domain,
15861                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
15862                 NULL, 0, "The server's primary domain", HFILL }},
15863
15864         { &hf_smb_server,
15865                 { "Server", "smb.server", FT_STRING, BASE_NONE,
15866                 NULL, 0, "The name of the DC/server", HFILL }},
15867
15868         { &hf_smb_max_raw_buf_size,
15869                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
15870                 NULL, 0, "Maximum raw buffer size", HFILL }},
15871
15872         { &hf_smb_server_guid,
15873                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
15874                 NULL, 0, "Globally unique identifier for this server", HFILL }},
15875
15876         { &hf_smb_security_blob_len,
15877                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
15878                 NULL, 0, "Security blob length", HFILL }},
15879
15880         { &hf_smb_security_blob,
15881                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
15882                 NULL, 0, "Security blob", HFILL }},
15883
15884         { &hf_smb_sm_mode16,
15885                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
15886                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
15887
15888         { &hf_smb_sm_password16,
15889                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
15890                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
15891
15892         { &hf_smb_sm_mode,
15893                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
15894                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
15895
15896         { &hf_smb_sm_password,
15897                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
15898                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
15899
15900         { &hf_smb_sm_signatures,
15901                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
15902                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
15903
15904         { &hf_smb_sm_sig_required,
15905                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
15906                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
15907
15908         { &hf_smb_rm_read,
15909                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
15910                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
15911
15912         { &hf_smb_rm_write,
15913                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
15914                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
15915
15916         { &hf_smb_server_date_time,
15917                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
15918                 NULL, 0, "Current date and time at server", HFILL }},
15919
15920         { &hf_smb_server_smb_date,
15921                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
15922                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
15923
15924         { &hf_smb_server_smb_time,
15925                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
15926                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
15927
15928         { &hf_smb_server_cap_raw_mode,
15929                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
15930                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
15931
15932         { &hf_smb_server_cap_mpx_mode,
15933                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
15934                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
15935
15936         { &hf_smb_server_cap_unicode,
15937                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
15938                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
15939
15940         { &hf_smb_server_cap_large_files,
15941                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
15942                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
15943
15944         { &hf_smb_server_cap_nt_smbs,
15945                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
15946                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
15947
15948         { &hf_smb_server_cap_rpc_remote_apis,
15949                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
15950                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
15951
15952         { &hf_smb_server_cap_nt_status,
15953                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
15954                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
15955
15956         { &hf_smb_server_cap_level_ii_oplocks,
15957                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
15958                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
15959
15960         { &hf_smb_server_cap_lock_and_read,
15961                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
15962                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
15963
15964         { &hf_smb_server_cap_nt_find,
15965                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
15966                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
15967
15968         { &hf_smb_server_cap_dfs,
15969                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
15970                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
15971
15972         { &hf_smb_server_cap_infolevel_passthru,
15973                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
15974                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
15975
15976         { &hf_smb_server_cap_large_readx,
15977                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
15978                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
15979
15980         { &hf_smb_server_cap_large_writex,
15981                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
15982                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
15983
15984         { &hf_smb_server_cap_unix,
15985                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
15986                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
15987
15988         { &hf_smb_server_cap_reserved,
15989                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
15990                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
15991
15992         { &hf_smb_server_cap_bulk_transfer,
15993                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
15994                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
15995
15996         { &hf_smb_server_cap_compressed_data,
15997                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
15998                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
15999
16000         { &hf_smb_server_cap_extended_security,
16001                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
16002                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
16003
16004         { &hf_smb_system_time,
16005                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
16006                 NULL, 0, "System Time", HFILL }},
16007
16008         { &hf_smb_unknown,
16009                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
16010                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
16011
16012         { &hf_smb_dir_name,
16013                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
16014                 NULL, 0, "SMB Directory Name", HFILL }},
16015
16016         { &hf_smb_echo_count,
16017                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
16018                 NULL, 0, "Number of times to echo data back", HFILL }},
16019
16020         { &hf_smb_echo_data,
16021                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
16022                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
16023
16024         { &hf_smb_echo_seq_num,
16025                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
16026                 NULL, 0, "Sequence number for this echo response", HFILL }},
16027
16028         { &hf_smb_max_buf_size,
16029                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
16030                 NULL, 0, "Max client buffer size", HFILL }},
16031
16032         { &hf_smb_path,
16033                 { "Path", "smb.path", FT_STRING, BASE_NONE,
16034                 NULL, 0, "Path. Server name and share name", HFILL }},
16035
16036         { &hf_smb_service,
16037                 { "Service", "smb.service", FT_STRING, BASE_NONE,
16038                 NULL, 0, "Service name", HFILL }},
16039
16040         { &hf_smb_password,
16041                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
16042                 NULL, 0, "Password", HFILL }},
16043
16044         { &hf_smb_ansi_password,
16045                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
16046                 NULL, 0, "ANSI Password", HFILL }},
16047
16048         { &hf_smb_unicode_password,
16049                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
16050                 NULL, 0, "Unicode Password", HFILL }},
16051
16052         { &hf_smb_move_flags_file,
16053                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
16054                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
16055
16056         { &hf_smb_move_flags_dir,
16057                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
16058                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
16059
16060         { &hf_smb_move_flags_verify,
16061                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
16062                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
16063
16064         { &hf_smb_files_moved,
16065                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
16066                 NULL, 0, "Number of files moved", HFILL }},
16067
16068         { &hf_smb_copy_flags_file,
16069                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
16070                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
16071
16072         { &hf_smb_copy_flags_dir,
16073                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
16074                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
16075
16076         { &hf_smb_copy_flags_dest_mode,
16077                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
16078                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
16079
16080         { &hf_smb_copy_flags_source_mode,
16081                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
16082                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
16083
16084         { &hf_smb_copy_flags_verify,
16085                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
16086                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
16087
16088         { &hf_smb_copy_flags_tree_copy,
16089                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
16090                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
16091
16092         { &hf_smb_copy_flags_ea_action,
16093                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
16094                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
16095
16096         { &hf_smb_count,
16097                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
16098                 NULL, 0, "Count number of items/bytes", HFILL }},
16099
16100         { &hf_smb_file_name,
16101                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
16102                 NULL, 0, "File Name", HFILL }},
16103
16104         { &hf_smb_open_function_create,
16105                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
16106                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
16107
16108         { &hf_smb_open_function_open,
16109                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
16110                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
16111
16112         { &hf_smb_fid,
16113                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
16114                 NULL, 0, "FID: File ID", HFILL }},
16115
16116         { &hf_smb_file_attr_read_only_16bit,
16117                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
16118                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16119
16120         { &hf_smb_file_attr_read_only_8bit,
16121                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
16122                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16123
16124         { &hf_smb_file_attr_hidden_16bit,
16125                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
16126                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16127
16128         { &hf_smb_file_attr_hidden_8bit,
16129                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
16130                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16131
16132         { &hf_smb_file_attr_system_16bit,
16133                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
16134                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16135
16136         { &hf_smb_file_attr_system_8bit,
16137                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
16138                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16139
16140         { &hf_smb_file_attr_volume_16bit,
16141                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
16142                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
16143
16144         { &hf_smb_file_attr_volume_8bit,
16145                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
16146                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
16147
16148         { &hf_smb_file_attr_directory_16bit,
16149                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
16150                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16151
16152         { &hf_smb_file_attr_directory_8bit,
16153                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
16154                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16155
16156         { &hf_smb_file_attr_archive_16bit,
16157                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
16158                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16159
16160         { &hf_smb_file_attr_archive_8bit,
16161                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
16162                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16163
16164         { &hf_smb_file_attr_device,
16165                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
16166                 TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
16167
16168         { &hf_smb_file_attr_normal,
16169                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
16170                 TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
16171
16172         { &hf_smb_file_attr_temporary,
16173                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
16174                 TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
16175
16176         { &hf_smb_file_attr_sparse,
16177                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
16178                 TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
16179
16180         { &hf_smb_file_attr_reparse,
16181                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
16182                 TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
16183
16184         { &hf_smb_file_attr_compressed,
16185                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
16186                 TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
16187
16188         { &hf_smb_file_attr_offline,
16189                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
16190                 TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
16191
16192         { &hf_smb_file_attr_not_content_indexed,
16193                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
16194                 TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
16195
16196         { &hf_smb_file_attr_encrypted,
16197                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
16198                 TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
16199
16200         { &hf_smb_file_size,
16201                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
16202                 NULL, 0, "File Size", HFILL }},
16203
16204         { &hf_smb_search_attribute_read_only,
16205                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
16206                 TFS(&tfs_search_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
16207
16208         { &hf_smb_search_attribute_hidden,
16209                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
16210                 TFS(&tfs_search_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
16211
16212         { &hf_smb_search_attribute_system,
16213                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
16214                 TFS(&tfs_search_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
16215
16216         { &hf_smb_search_attribute_volume,
16217                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
16218                 TFS(&tfs_search_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
16219
16220         { &hf_smb_search_attribute_directory,
16221                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
16222                 TFS(&tfs_search_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
16223
16224         { &hf_smb_search_attribute_archive,
16225                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
16226                 TFS(&tfs_search_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
16227
16228         { &hf_smb_access_mode,
16229                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
16230                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
16231
16232         { &hf_smb_access_sharing,
16233                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
16234                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
16235
16236         { &hf_smb_access_locality,
16237                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
16238                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
16239
16240         { &hf_smb_access_caching,
16241                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
16242                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
16243
16244         { &hf_smb_access_writetru,
16245                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
16246                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
16247
16248         { &hf_smb_create_time,
16249                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
16250                 NULL, 0, "Creation Time", HFILL }},
16251
16252         { &hf_smb_modify_time,
16253                 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
16254                   NULL, 0, "Modification Time", HFILL }},
16255
16256         { &hf_smb_backup_time,
16257                 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
16258                   NULL, 0, "Backup time", HFILL}},
16259
16260         { &hf_smb_mac_alloc_block_count,
16261                 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
16262                   NULL, 0, "Allocation Block Count", HFILL}},
16263
16264         { &hf_smb_mac_alloc_block_size,
16265                 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
16266                   NULL, 0, "Allocation Block Size", HFILL}},
16267
16268         { &hf_smb_mac_free_block_count,
16269                 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
16270                   NULL, 0, "Free Block Count", HFILL}},
16271
16272         { &hf_smb_mac_root_file_count,
16273                 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
16274                 NULL, 0, "Root File Count", HFILL}},
16275
16276         { &hf_smb_mac_root_dir_count,
16277           { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
16278             NULL, 0, "Root Directory Count", HFILL}},
16279
16280         { &hf_smb_mac_file_count,
16281           { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
16282             NULL, 0, "File Count", HFILL}},
16283
16284         { &hf_smb_mac_dir_count,
16285           { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
16286             NULL, 0, "Directory Count", HFILL}},
16287
16288         { &hf_smb_mac_support_flags,
16289           { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
16290             NULL, 0, "Mac Support Flags", HFILL}},
16291
16292         { &hf_smb_mac_sup_access_ctrl,
16293           { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
16294             TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
16295
16296         { &hf_smb_mac_sup_getset_comments,
16297           { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
16298             TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
16299
16300         { &hf_smb_mac_sup_desktopdb_calls,
16301           { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
16302             TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
16303
16304         { &hf_smb_mac_sup_unique_ids,
16305           { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
16306             TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
16307
16308         { &hf_smb_mac_sup_streams,
16309           { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
16310             TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
16311
16312         { &hf_smb_create_dos_date,
16313                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
16314                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
16315
16316         { &hf_smb_create_dos_time,
16317                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
16318                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
16319
16320         { &hf_smb_last_write_time,
16321                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
16322                 NULL, 0, "Time this file was last written to", HFILL }},
16323
16324         { &hf_smb_last_write_dos_date,
16325                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
16326                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
16327
16328         { &hf_smb_last_write_dos_time,
16329                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
16330                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
16331
16332         { &hf_smb_old_file_name,
16333                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
16334                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
16335
16336         { &hf_smb_offset,
16337                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
16338                 NULL, 0, "Offset in file", HFILL }},
16339
16340         { &hf_smb_remaining,
16341                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
16342                 NULL, 0, "Remaining number of bytes", HFILL }},
16343
16344         { &hf_smb_padding,
16345                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
16346                 NULL, 0, "Padding or unknown data", HFILL }},
16347
16348         { &hf_smb_file_data,
16349                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
16350                 NULL, 0, "Data read/written to the file", HFILL }},
16351
16352         { &hf_smb_mac_fndrinfo,
16353                 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_HEX,
16354                   NULL, 0, "Finder Info", HFILL}},
16355
16356         { &hf_smb_total_data_len,
16357                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
16358                 NULL, 0, "Total length of data", HFILL }},
16359
16360         { &hf_smb_data_len,
16361                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
16362                 NULL, 0, "Length of data", HFILL }},
16363
16364         { &hf_smb_seek_mode,
16365                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
16366                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
16367
16368         { &hf_smb_access_time,
16369                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
16370                 NULL, 0, "Last Access Time", HFILL }},
16371
16372         { &hf_smb_access_dos_date,
16373                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
16374                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
16375
16376         { &hf_smb_access_dos_time,
16377                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
16378                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
16379
16380         { &hf_smb_data_size,
16381                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
16382                 NULL, 0, "Data Size", HFILL }},
16383
16384         { &hf_smb_alloc_size,
16385                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
16386                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
16387
16388         { &hf_smb_max_count,
16389                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
16390                 NULL, 0, "Maximum Count", HFILL }},
16391
16392         { &hf_smb_min_count,
16393                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
16394                 NULL, 0, "Minimum Count", HFILL }},
16395
16396         { &hf_smb_timeout,
16397                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
16398                 NULL, 0, "Timeout in miliseconds", HFILL }},
16399
16400         { &hf_smb_high_offset,
16401                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
16402                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
16403
16404         { &hf_smb_units,
16405                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
16406                 NULL, 0, "Total number of units at server", HFILL }},
16407
16408         { &hf_smb_bpu,
16409                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
16410                 NULL, 0, "Blocks per unit at server", HFILL }},
16411
16412         { &hf_smb_blocksize,
16413                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
16414                 NULL, 0, "Block size (in bytes) at server", HFILL }},
16415
16416         { &hf_smb_freeunits,
16417                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
16418                 NULL, 0, "Number of free units at server", HFILL }},
16419
16420         { &hf_smb_data_offset,
16421                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
16422                 NULL, 0, "Data Offset", HFILL }},
16423
16424         { &hf_smb_dcm,
16425                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
16426                 NULL, 0, "Data Compaction Mode", HFILL }},
16427
16428         { &hf_smb_request_mask,
16429                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
16430                 NULL, 0, "Connectionless mode mask", HFILL }},
16431
16432         { &hf_smb_response_mask,
16433                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
16434                 NULL, 0, "Connectionless mode mask", HFILL }},
16435
16436         { &hf_smb_sid,
16437                 { "SID", "smb.sid", FT_UINT16, BASE_HEX,
16438                 NULL, 0, "SID: Search ID, handle for find operations", HFILL }},
16439
16440         { &hf_smb_write_mode_write_through,
16441                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
16442                 TFS(&tfs_write_mode_write_through), 0x0001, "Write through mode requested?", HFILL }},
16443
16444         { &hf_smb_write_mode_return_remaining,
16445                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
16446                 TFS(&tfs_write_mode_return_remaining), 0x0002, "Return remaining data responses?", HFILL }},
16447
16448         { &hf_smb_write_mode_raw,
16449                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
16450                 TFS(&tfs_write_mode_raw), 0x0004, "Use WriteRawNamedPipe?", HFILL }},
16451
16452         { &hf_smb_write_mode_message_start,
16453                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
16454                 TFS(&tfs_write_mode_message_start), 0x0008, "Is this the start of a message?", HFILL }},
16455
16456         { &hf_smb_write_mode_connectionless,
16457                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
16458                 TFS(&tfs_write_mode_connectionless), 0x0080, "Connectionless mode requested?", HFILL }},
16459
16460         { &hf_smb_resume_key_len,
16461                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
16462                 NULL, 0, "Resume Key length", HFILL }},
16463
16464         { &hf_smb_resume_find_id,
16465                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
16466                 NULL, 0, "Handle for Find operation", HFILL }},
16467
16468         { &hf_smb_resume_server_cookie,
16469                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
16470                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
16471
16472         { &hf_smb_resume_client_cookie,
16473                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
16474                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
16475
16476         { &hf_smb_andxoffset,
16477                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
16478                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
16479
16480         { &hf_smb_lock_type_large,
16481                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
16482                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
16483
16484         { &hf_smb_lock_type_cancel,
16485                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
16486                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
16487
16488         { &hf_smb_lock_type_change,
16489                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
16490                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
16491
16492         { &hf_smb_lock_type_oplock,
16493                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
16494                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
16495
16496         { &hf_smb_lock_type_shared,
16497                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
16498                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
16499
16500         { &hf_smb_locking_ol,
16501                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
16502                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
16503
16504         { &hf_smb_number_of_locks,
16505                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
16506                 NULL, 0, "Number of lock requests in this request", HFILL }},
16507
16508         { &hf_smb_number_of_unlocks,
16509                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
16510                 NULL, 0, "Number of unlock requests in this request", HFILL }},
16511
16512         { &hf_smb_lock_long_length,
16513                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
16514                 NULL, 0, "Length of lock/unlock region", HFILL }},
16515
16516         { &hf_smb_lock_long_offset,
16517                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
16518                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
16519
16520         { &hf_smb_file_type,
16521                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
16522                 VALS(filetype_vals), 0, "Type of file", HFILL }},
16523
16524         { &hf_smb_ipc_state_nonblocking,
16525                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
16526                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
16527
16528         { &hf_smb_ipc_state_endpoint,
16529                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
16530                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
16531
16532         { &hf_smb_ipc_state_pipe_type,
16533                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
16534                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
16535
16536         { &hf_smb_ipc_state_read_mode,
16537                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
16538                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
16539
16540         { &hf_smb_ipc_state_icount,
16541                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
16542                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
16543
16544         { &hf_smb_server_fid,
16545                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
16546                 NULL, 0, "Server unique File ID", HFILL }},
16547
16548         { &hf_smb_open_flags_add_info,
16549                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
16550                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
16551
16552         { &hf_smb_open_flags_ex_oplock,
16553                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
16554                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
16555
16556         { &hf_smb_open_flags_batch_oplock,
16557                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
16558                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
16559
16560         { &hf_smb_open_flags_ealen,
16561                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
16562                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
16563
16564         { &hf_smb_open_action_open,
16565                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
16566                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
16567
16568         { &hf_smb_open_action_lock,
16569                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
16570                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
16571
16572         { &hf_smb_vc_num,
16573                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
16574                 NULL, 0, "VC Number", HFILL }},
16575
16576         { &hf_smb_password_len,
16577                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
16578                 NULL, 0, "Length of password", HFILL }},
16579
16580         { &hf_smb_ansi_password_len,
16581                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
16582                 NULL, 0, "Length of ANSI password", HFILL }},
16583
16584         { &hf_smb_unicode_password_len,
16585                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
16586                 NULL, 0, "Length of Unicode password", HFILL }},
16587
16588         { &hf_smb_account,
16589                 { "Account", "smb.account", FT_STRING, BASE_NONE,
16590                 NULL, 0, "Account, username", HFILL }},
16591
16592         { &hf_smb_os,
16593                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
16594                 NULL, 0, "Which OS we are running", HFILL }},
16595
16596         { &hf_smb_lanman,
16597                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
16598                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
16599
16600         { &hf_smb_setup_action_guest,
16601                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
16602                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
16603
16604         { &hf_smb_fs,
16605                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
16606                 NULL, 0, "Native File System", HFILL }},
16607
16608         { &hf_smb_connect_flags_dtid,
16609                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
16610                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
16611
16612         { &hf_smb_connect_support_search,
16613                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
16614                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
16615
16616         { &hf_smb_connect_support_in_dfs,
16617                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
16618                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
16619
16620         { &hf_smb_max_setup_count,
16621                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
16622                 NULL, 0, "Maximum number of setup words to return", HFILL }},
16623
16624         { &hf_smb_total_param_count,
16625                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
16626                 NULL, 0, "Total number of parameter bytes", HFILL }},
16627
16628         { &hf_smb_total_data_count,
16629                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
16630                 NULL, 0, "Total number of data bytes", HFILL }},
16631
16632         { &hf_smb_max_param_count,
16633                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
16634                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
16635
16636         { &hf_smb_max_data_count,
16637                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
16638                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
16639
16640         { &hf_smb_param_disp16,
16641                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
16642                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
16643
16644         { &hf_smb_param_count16,
16645                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
16646                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
16647
16648         { &hf_smb_param_offset16,
16649                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
16650                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
16651
16652         { &hf_smb_param_disp32,
16653                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
16654                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
16655
16656         { &hf_smb_param_count32,
16657                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
16658                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
16659
16660         { &hf_smb_param_offset32,
16661                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
16662                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
16663
16664         { &hf_smb_data_count16,
16665                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
16666                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
16667
16668         { &hf_smb_data_disp16,
16669                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
16670                 NULL, 0, "Data Displacement", HFILL }},
16671
16672         { &hf_smb_data_offset16,
16673                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
16674                 NULL, 0, "Data Offset", HFILL }},
16675
16676         { &hf_smb_data_count32,
16677                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
16678                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
16679
16680         { &hf_smb_data_disp32,
16681                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
16682                 NULL, 0, "Data Displacement", HFILL }},
16683
16684         { &hf_smb_data_offset32,
16685                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
16686                 NULL, 0, "Data Offset", HFILL }},
16687
16688         { &hf_smb_setup_count,
16689                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
16690                 NULL, 0, "Number of setup words in this buffer", HFILL }},
16691
16692         { &hf_smb_nt_trans_subcmd,
16693                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
16694                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
16695
16696         { &hf_smb_nt_ioctl_function_code,
16697                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
16698                 NULL, 0, "NT IOCTL function code", HFILL }},
16699
16700         { &hf_smb_nt_ioctl_isfsctl,
16701                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
16702                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
16703
16704         { &hf_smb_nt_ioctl_flags_root_handle,
16705                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
16706                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
16707
16708         { &hf_smb_nt_ioctl_data,
16709                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
16710                 NULL, 0, "Data for the IOCTL call", HFILL }},
16711
16712         { &hf_smb_nt_notify_action,
16713                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
16714                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
16715
16716         { &hf_smb_nt_notify_watch_tree,
16717                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
16718                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
16719
16720         { &hf_smb_nt_notify_stream_write,
16721                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
16722                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
16723
16724         { &hf_smb_nt_notify_stream_size,
16725                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
16726                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
16727
16728         { &hf_smb_nt_notify_stream_name,
16729                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
16730                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
16731
16732         { &hf_smb_nt_notify_security,
16733                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
16734                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
16735
16736         { &hf_smb_nt_notify_ea,
16737                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
16738                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
16739
16740         { &hf_smb_nt_notify_creation,
16741                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
16742                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
16743
16744         { &hf_smb_nt_notify_last_access,
16745                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
16746                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
16747
16748         { &hf_smb_nt_notify_last_write,
16749                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
16750                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
16751
16752         { &hf_smb_nt_notify_size,
16753                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
16754                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
16755
16756         { &hf_smb_nt_notify_attributes,
16757                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
16758                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
16759
16760         { &hf_smb_nt_notify_dir_name,
16761                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
16762                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
16763
16764         { &hf_smb_nt_notify_file_name,
16765                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
16766                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
16767
16768         { &hf_smb_root_dir_fid,
16769                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
16770                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
16771
16772         { &hf_smb_alloc_size64,
16773                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
16774                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
16775
16776         { &hf_smb_nt_create_disposition,
16777                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
16778                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
16779
16780         { &hf_smb_sd_length,
16781                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
16782                 NULL, 0, "Total length of security descriptor", HFILL }},
16783
16784         { &hf_smb_ea_length,
16785                 { "EA Length", "smb.ea.length", FT_UINT32, BASE_DEC,
16786                 NULL, 0, "Total EA length for opened file", HFILL }},
16787
16788         { &hf_smb_file_name_len,
16789                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
16790                 NULL, 0, "Length of File Name", HFILL }},
16791
16792         { &hf_smb_nt_impersonation_level,
16793                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
16794                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
16795
16796         { &hf_smb_nt_security_flags_context_tracking,
16797                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
16798                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
16799
16800         { &hf_smb_nt_security_flags_effective_only,
16801                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
16802                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
16803
16804         { &hf_smb_nt_access_mask_generic_read,
16805                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
16806                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
16807
16808         { &hf_smb_nt_access_mask_generic_write,
16809                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
16810                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
16811
16812         { &hf_smb_nt_access_mask_generic_execute,
16813                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
16814                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
16815
16816         { &hf_smb_nt_access_mask_generic_all,
16817                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
16818                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
16819
16820         { &hf_smb_nt_access_mask_maximum_allowed,
16821                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
16822                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
16823
16824         { &hf_smb_nt_access_mask_system_security,
16825                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
16826                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
16827
16828         { &hf_smb_nt_access_mask_synchronize,
16829                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
16830                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
16831
16832         { &hf_smb_nt_access_mask_write_owner,
16833                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
16834                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
16835
16836         { &hf_smb_nt_access_mask_write_dac,
16837                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
16838                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
16839
16840         { &hf_smb_nt_access_mask_read_control,
16841                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
16842                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
16843
16844         { &hf_smb_nt_access_mask_delete,
16845                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
16846                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
16847
16848         { &hf_smb_nt_access_mask_write_attributes,
16849                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
16850                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
16851
16852         { &hf_smb_nt_access_mask_read_attributes,
16853                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
16854                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
16855
16856         { &hf_smb_nt_access_mask_delete_child,
16857                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
16858                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
16859
16860         /*
16861          * "Execute" for files, "traverse" for directories.
16862          */
16863         { &hf_smb_nt_access_mask_execute,
16864                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
16865                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
16866
16867         { &hf_smb_nt_access_mask_write_ea,
16868                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
16869                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
16870
16871         { &hf_smb_nt_access_mask_read_ea,
16872                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
16873                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
16874
16875         /*
16876          * "Append data" for files, "add subdirectory" for directories,
16877          * "create pipe instance" for named pipes.
16878          */
16879         { &hf_smb_nt_access_mask_append,
16880                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
16881                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
16882
16883         /*
16884          * "Write data" for files and pipes, "add file" for directory.
16885          */
16886         { &hf_smb_nt_access_mask_write,
16887                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
16888                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
16889
16890         /*
16891          * "Read data" for files and pipes, "list directory" for directory.
16892          */
16893         { &hf_smb_nt_access_mask_read,
16894                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
16895                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
16896
16897         { &hf_smb_nt_create_bits_oplock,
16898                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
16899                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
16900
16901         { &hf_smb_nt_create_bits_boplock,
16902                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
16903                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
16904
16905         { &hf_smb_nt_create_bits_dir,
16906                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
16907                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
16908
16909         { &hf_smb_nt_create_options_directory_file,
16910                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
16911                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
16912
16913         { &hf_smb_nt_create_options_write_through,
16914                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
16915                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
16916
16917         { &hf_smb_nt_create_options_sequential_only,
16918                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
16919                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
16920
16921         { &hf_smb_nt_create_options_sync_io_alert,
16922                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
16923                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
16924
16925         { &hf_smb_nt_create_options_sync_io_nonalert,
16926                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
16927                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
16928
16929         { &hf_smb_nt_create_options_non_directory_file,
16930                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
16931                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
16932
16933         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
16934            and "NtOpenFile()"; is that sent over the wire?  Network
16935            Monitor thinks so, but its author may just have grabbed
16936            the flag bits from a system header file. */
16937
16938         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
16939            and "NtOpenFile()"; is that sent over the wire?  NetMon
16940            thinks so, but see previous comment. */
16941
16942         { &hf_smb_nt_create_options_no_ea_knowledge,
16943                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
16944                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
16945
16946         { &hf_smb_nt_create_options_eight_dot_three_only,
16947                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
16948                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
16949
16950         { &hf_smb_nt_create_options_random_access,
16951                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
16952                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
16953
16954         { &hf_smb_nt_create_options_delete_on_close,
16955                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
16956                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
16957
16958         /* 0x00002000 is "open by FID", or something such as that (which
16959            I suspect is like "open by inumber" on UNIX), at least in
16960            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
16961            wire?  NetMon thinks so, but see previous comment. */
16962
16963         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
16964            and "NtOpenFile()"; is that sent over the wire?  NetMon
16965            thinks so, but see previous comment. */
16966
16967         { &hf_smb_nt_share_access_read,
16968                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
16969                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
16970
16971         { &hf_smb_nt_share_access_write,
16972                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
16973                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
16974
16975         { &hf_smb_nt_share_access_delete,
16976                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
16977                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
16978
16979         { &hf_smb_file_eattr_read_only,
16980                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
16981                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16982
16983         { &hf_smb_file_eattr_hidden,
16984                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
16985                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16986
16987         { &hf_smb_file_eattr_system,
16988                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
16989                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16990
16991         { &hf_smb_file_eattr_volume,
16992                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
16993                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
16994
16995         { &hf_smb_file_eattr_directory,
16996                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
16997                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16998
16999         { &hf_smb_file_eattr_archive,
17000                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
17001                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17002
17003         { &hf_smb_file_eattr_device,
17004                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
17005                 TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
17006
17007         { &hf_smb_file_eattr_normal,
17008                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
17009                 TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
17010
17011         { &hf_smb_file_eattr_temporary,
17012                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
17013                 TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
17014
17015         { &hf_smb_file_eattr_sparse,
17016                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
17017                 TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
17018
17019         { &hf_smb_file_eattr_reparse,
17020                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
17021                 TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
17022
17023         { &hf_smb_file_eattr_compressed,
17024                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
17025                 TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
17026
17027         { &hf_smb_file_eattr_offline,
17028                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
17029                 TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
17030
17031         { &hf_smb_file_eattr_not_content_indexed,
17032                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
17033                 TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
17034
17035         { &hf_smb_file_eattr_encrypted,
17036                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
17037                 TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
17038
17039         { &hf_smb_file_eattr_write_through,
17040                 { "Write Through", "smb.file_attribute.write_through", FT_BOOLEAN, 32,
17041                 TFS(&tfs_file_attribute_write_through), FILE_ATTRIBUTE_WRITE_THROUGH, "Does this object need write through?", HFILL }},
17042
17043         { &hf_smb_file_eattr_no_buffering,
17044                 { "No Buffering", "smb.file_attribute.no_buffering", FT_BOOLEAN, 32,
17045                 TFS(&tfs_file_attribute_no_buffering), FILE_ATTRIBUTE_NO_BUFFERING, "May the server buffer this object?", HFILL }},
17046
17047         { &hf_smb_file_eattr_random_access,
17048                 { "Random Access", "smb.file_attribute.random_access", FT_BOOLEAN, 32,
17049                 TFS(&tfs_file_attribute_random_access), FILE_ATTRIBUTE_RANDOM_ACCESS, "Optimize for random access", HFILL }},
17050
17051         { &hf_smb_file_eattr_sequential_scan,
17052                 { "Sequential Scan", "smb.file_attribute.sequential_scan", FT_BOOLEAN, 32,
17053                 TFS(&tfs_file_attribute_sequential_scan), FILE_ATTRIBUTE_SEQUENTIAL_SCAN, "Optimize for sequential scan", HFILL }},
17054
17055         { &hf_smb_file_eattr_delete_on_close,
17056                 { "Delete on Close", "smb.file_attribute.delete_on_close", FT_BOOLEAN, 32,
17057                 TFS(&tfs_file_attribute_delete_on_close), FILE_ATTRIBUTE_DELETE_ON_CLOSE, "Should this object be deleted on close?", HFILL }},
17058
17059         { &hf_smb_file_eattr_backup_semantics,
17060                 { "Backup", "smb.file_attribute.backup_semantics", FT_BOOLEAN, 32,
17061                 TFS(&tfs_file_attribute_backup_semantics), FILE_ATTRIBUTE_BACKUP_SEMANTICS, "Does this object need/support backup semantics", HFILL }},
17062
17063         { &hf_smb_file_eattr_posix_semantics,
17064                 { "Posix", "smb.file_attribute.posix_semantics", FT_BOOLEAN, 32,
17065                 TFS(&tfs_file_attribute_posix_semantics), FILE_ATTRIBUTE_POSIX_SEMANTICS, "Does this object need/support POSIX semantics?", HFILL }},
17066
17067         { &hf_smb_sec_desc_len,
17068                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
17069                 NULL, 0, "Security Descriptor Length", HFILL }},
17070
17071         { &hf_smb_nt_qsd_owner,
17072                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
17073                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
17074
17075         { &hf_smb_nt_qsd_group,
17076                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
17077                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
17078
17079         { &hf_smb_nt_qsd_dacl,
17080                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
17081                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
17082
17083         { &hf_smb_nt_qsd_sacl,
17084                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
17085                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
17086
17087         { &hf_smb_extended_attributes,
17088                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
17089                 NULL, 0, "Extended Attributes", HFILL }},
17090
17091         { &hf_smb_oplock_level,
17092                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
17093                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
17094
17095         { &hf_smb_create_action,
17096                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
17097                 VALS(create_disposition_vals), 0, "Type of action taken", HFILL }},
17098
17099         { &hf_smb_file_id,
17100                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
17101                 NULL, 0, "Server unique file ID", HFILL }},
17102
17103         { &hf_smb_ea_error_offset,
17104                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
17105                 NULL, 0, "Offset into EA list if EA error", HFILL }},
17106
17107         { &hf_smb_end_of_file,
17108                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
17109                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
17110
17111         { &hf_smb_device_type,
17112                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
17113                 VALS(device_type_vals), 0, "Type of device", HFILL }},
17114
17115         { &hf_smb_is_directory,
17116                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
17117                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
17118
17119         { &hf_smb_next_entry_offset,
17120                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
17121                 NULL, 0, "Offset to next entry", HFILL }},
17122
17123         { &hf_smb_change_time,
17124                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
17125                 NULL, 0, "Last Change Time", HFILL }},
17126
17127         { &hf_smb_setup_len,
17128                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
17129                 NULL, 0, "Length of printer setup data", HFILL }},
17130
17131         { &hf_smb_print_mode,
17132                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
17133                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
17134
17135         { &hf_smb_print_identifier,
17136                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
17137                 NULL, 0, "Identifier string for this print job", HFILL }},
17138
17139         { &hf_smb_restart_index,
17140                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
17141                 NULL, 0, "Index of entry after last returned", HFILL }},
17142
17143         { &hf_smb_print_queue_date,
17144                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
17145                 NULL, 0, "Date when this entry was queued", HFILL }},
17146
17147         { &hf_smb_print_queue_dos_date,
17148                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
17149                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
17150
17151         { &hf_smb_print_queue_dos_time,
17152                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
17153                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
17154
17155         { &hf_smb_print_status,
17156                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
17157                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
17158
17159         { &hf_smb_print_spool_file_number,
17160                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
17161                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
17162
17163         { &hf_smb_print_spool_file_size,
17164                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
17165                 NULL, 0, "Number of bytes in spool file", HFILL }},
17166
17167         { &hf_smb_print_spool_file_name,
17168                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
17169                 NULL, 0, "Name of client that submitted this job", HFILL }},
17170
17171         { &hf_smb_start_index,
17172                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
17173                 NULL, 0, "First queue entry to return", HFILL }},
17174
17175         { &hf_smb_originator_name,
17176                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
17177                 NULL, 0, "Name of sender of message", HFILL }},
17178
17179         { &hf_smb_destination_name,
17180                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
17181                 NULL, 0, "Name of recipient of message", HFILL }},
17182
17183         { &hf_smb_message_len,
17184                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
17185                 NULL, 0, "Length of message", HFILL }},
17186
17187         { &hf_smb_message,
17188                 { "Message", "smb.message", FT_STRING, BASE_NONE,
17189                 NULL, 0, "Message text", HFILL }},
17190
17191         { &hf_smb_mgid,
17192                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
17193                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
17194
17195         { &hf_smb_forwarded_name,
17196                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
17197                 NULL, 0, "Recipient name being forwarded", HFILL }},
17198
17199         { &hf_smb_machine_name,
17200                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
17201                 NULL, 0, "Name of target machine", HFILL }},
17202
17203         { &hf_smb_cancel_to,
17204                 { "Cancel to", "smb.cancel_to", FT_UINT32, BASE_DEC,
17205                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
17206
17207         { &hf_smb_trans2_subcmd,
17208                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
17209                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
17210
17211         { &hf_smb_trans_name,
17212                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
17213                 NULL, 0, "Name of transaction", HFILL }},
17214
17215         { &hf_smb_transaction_flags_dtid,
17216                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
17217                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
17218
17219         { &hf_smb_transaction_flags_owt,
17220                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
17221                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
17222
17223         { &hf_smb_search_count,
17224                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
17225                 NULL, 0, "Maximum number of search entries to return", HFILL }},
17226
17227         { &hf_smb_search_pattern,
17228                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
17229                 NULL, 0, "Search Pattern", HFILL }},
17230
17231         { &hf_smb_ff2_backup,
17232                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
17233                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
17234
17235         { &hf_smb_ff2_continue,
17236                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
17237                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
17238
17239         { &hf_smb_ff2_resume,
17240                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
17241                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
17242
17243         { &hf_smb_ff2_close_eos,
17244                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
17245                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
17246
17247         { &hf_smb_ff2_close,
17248                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
17249                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
17250
17251         { &hf_smb_ff2_information_level,
17252                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
17253                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
17254
17255         { &hf_smb_qpi_loi,
17256                 { "Level of Interest", "smb.loi", FT_UINT16, BASE_DEC,
17257                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] commands", HFILL }},
17258
17259 #if 0
17260         { &hf_smb_sfi_writetru,
17261                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
17262                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
17263
17264         { &hf_smb_sfi_caching,
17265                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
17266                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
17267 #endif
17268
17269         { &hf_smb_storage_type,
17270                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
17271                 NULL, 0, "Type of storage", HFILL }},
17272
17273         { &hf_smb_resume,
17274                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
17275                 NULL, 0, "Resume Key", HFILL }},
17276
17277         { &hf_smb_max_referral_level,
17278                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
17279                 NULL, 0, "Latest referral version number understood", HFILL }},
17280
17281         { &hf_smb_qfsi_information_level,
17282                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_HEX,
17283                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
17284
17285         { &hf_smb_nt_rename_level,
17286                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
17287                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
17288
17289         { &hf_smb_cluster_count,
17290                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
17291                 NULL, 0, "Number of clusters", HFILL }},
17292
17293         { &hf_smb_ea_size,
17294                 { "EA Size", "smb.ea_size", FT_UINT32, BASE_DEC,
17295                 NULL, 0, "Size of file's EA information", HFILL }},
17296
17297         { &hf_smb_list_length,
17298                 { "ListLength", "smb.list_len", FT_UINT32, BASE_DEC,
17299                 NULL, 0, "Length of the remaining data", HFILL }},
17300
17301         { &hf_smb_number_of_links,
17302                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
17303                 NULL, 0, "Number of hard links to the file", HFILL }},
17304
17305         { &hf_smb_delete_pending,
17306                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
17307                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
17308
17309         { &hf_smb_index_number,
17310                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
17311                 NULL, 0, "File system unique identifier", HFILL }},
17312
17313         { &hf_smb_current_offset,
17314                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
17315                 NULL, 0, "Current offset in the file", HFILL }},
17316
17317         { &hf_smb_t2_alignment,
17318                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
17319                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
17320
17321         { &hf_smb_t2_stream_name_length,
17322                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
17323                 NULL, 0, "Length of stream name", HFILL }},
17324
17325         { &hf_smb_t2_stream_size,
17326                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
17327                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
17328
17329         { &hf_smb_t2_stream_name,
17330                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
17331                 NULL, 0, "Name of the stream", HFILL }},
17332
17333         { &hf_smb_t2_compressed_file_size,
17334                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
17335                 NULL, 0, "Size of the compressed file", HFILL }},
17336
17337         { &hf_smb_t2_compressed_format,
17338                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
17339                 NULL, 0, "Compression algorithm used", HFILL }},
17340
17341         { &hf_smb_t2_compressed_unit_shift,
17342                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
17343                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
17344
17345         { &hf_smb_t2_compressed_chunk_shift,
17346                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
17347                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
17348
17349         { &hf_smb_t2_compressed_cluster_shift,
17350                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
17351                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
17352
17353         { &hf_smb_dfs_path_consumed,
17354                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
17355                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
17356
17357         { &hf_smb_dfs_num_referrals,
17358                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
17359                 NULL, 0, "Number of referrals in this pdu", HFILL }},
17360
17361         { &hf_smb_get_dfs_server_hold_storage,
17362                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
17363                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
17364
17365         { &hf_smb_get_dfs_fielding,
17366                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
17367                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
17368
17369         { &hf_smb_dfs_referral_version,
17370                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
17371                 NULL, 0, "Version of referral element", HFILL }},
17372
17373         { &hf_smb_dfs_referral_size,
17374                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
17375                 NULL, 0, "Size of referral element", HFILL }},
17376
17377         { &hf_smb_dfs_referral_server_type,
17378                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
17379                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
17380
17381         { &hf_smb_dfs_referral_flags_strip,
17382                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
17383                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
17384
17385         { &hf_smb_dfs_referral_node_offset,
17386                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
17387                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
17388
17389         { &hf_smb_dfs_referral_node,
17390                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
17391                 NULL, 0, "Name of entity to visit next", HFILL }},
17392
17393         { &hf_smb_dfs_referral_proximity,
17394                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
17395                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
17396
17397         { &hf_smb_dfs_referral_ttl,
17398                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
17399                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
17400
17401         { &hf_smb_dfs_referral_path_offset,
17402                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
17403                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
17404
17405         { &hf_smb_dfs_referral_path,
17406                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
17407                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
17408
17409         { &hf_smb_dfs_referral_alt_path_offset,
17410                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
17411                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
17412
17413         { &hf_smb_dfs_referral_alt_path,
17414                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
17415                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
17416
17417         { &hf_smb_end_of_search,
17418                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
17419                 NULL, 0, "Was last entry returned?", HFILL }},
17420
17421         { &hf_smb_last_name_offset,
17422                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
17423                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
17424
17425         { &hf_smb_fn_information_level,
17426                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
17427                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
17428
17429         { &hf_smb_monitor_handle,
17430                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
17431                 NULL, 0, "Handle for Find Notify operations", HFILL }},
17432
17433         { &hf_smb_change_count,
17434                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
17435                 NULL, 0, "Number of changes to wait for", HFILL }},
17436
17437         { &hf_smb_file_index,
17438                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
17439                 NULL, 0, "File index", HFILL }},
17440
17441         { &hf_smb_short_file_name,
17442                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
17443                 NULL, 0, "Short (8.3) File Name", HFILL }},
17444
17445         { &hf_smb_short_file_name_len,
17446                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
17447                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
17448
17449         { &hf_smb_fs_id,
17450                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
17451                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
17452
17453         { &hf_smb_sector_unit,
17454                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
17455                 NULL, 0, "Sectors per allocation unit", HFILL }},
17456
17457         { &hf_smb_fs_units,
17458                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
17459                 NULL, 0, "Total number of units on this filesystem", HFILL }},
17460
17461         { &hf_smb_fs_sector,
17462                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
17463                 NULL, 0, "Bytes per sector", HFILL }},
17464
17465         { &hf_smb_avail_units,
17466                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
17467                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
17468
17469         { &hf_smb_volume_serial_num,
17470                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
17471                 NULL, 0, "Volume serial number", HFILL }},
17472
17473         { &hf_smb_volume_label_len,
17474                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
17475                 NULL, 0, "Length of volume label", HFILL }},
17476
17477         { &hf_smb_volume_label,
17478                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
17479                 NULL, 0, "Volume label", HFILL }},
17480
17481         { &hf_smb_free_alloc_units64,
17482                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
17483                 NULL, 0, "Number of free allocation units", HFILL }},
17484
17485         { &hf_smb_caller_free_alloc_units64,
17486                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
17487                 NULL, 0, "Number of caller free allocation units", HFILL }},
17488
17489         { &hf_smb_actual_free_alloc_units64,
17490                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
17491                 NULL, 0, "Number of actual free allocation units", HFILL }},
17492
17493         { &hf_smb_soft_quota_limit,
17494                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
17495                 NULL, 0, "Soft Quota treshold", HFILL }},
17496
17497         { &hf_smb_hard_quota_limit,
17498                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
17499                 NULL, 0, "Hard Quota limit", HFILL }},
17500
17501         { &hf_smb_user_quota_used,
17502                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
17503                 NULL, 0, "How much Quota is used by this user", HFILL }},
17504
17505         { &hf_smb_max_name_len,
17506                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
17507                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
17508
17509         { &hf_smb_fs_name_len,
17510                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
17511                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
17512
17513         { &hf_smb_fs_name,
17514                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
17515                 NULL, 0, "Name of filesystem", HFILL }},
17516
17517         { &hf_smb_device_char_removable,
17518                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
17519                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
17520
17521         { &hf_smb_device_char_read_only,
17522                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
17523                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
17524
17525         { &hf_smb_device_char_floppy,
17526                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
17527                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
17528
17529         { &hf_smb_device_char_write_once,
17530                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
17531                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
17532
17533         { &hf_smb_device_char_remote,
17534                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
17535                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
17536
17537         { &hf_smb_device_char_mounted,
17538                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
17539                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
17540
17541         { &hf_smb_device_char_virtual,
17542                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
17543                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
17544
17545         { &hf_smb_fs_attr_css,
17546                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
17547                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
17548
17549         { &hf_smb_fs_attr_cpn,
17550                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
17551                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
17552
17553         { &hf_smb_fs_attr_pacls,
17554                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
17555                 TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
17556
17557         { &hf_smb_fs_attr_fc,
17558                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
17559                 TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
17560
17561         { &hf_smb_fs_attr_vq,
17562                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
17563                 TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
17564
17565         { &hf_smb_fs_attr_dim,
17566                 { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
17567                 TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
17568
17569         { &hf_smb_fs_attr_vic,
17570                 { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
17571                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
17572
17573         { &hf_smb_sec_desc_revision,
17574                 { "Revision", "smb.sec_desc.revision", FT_UINT16, BASE_DEC,
17575                 NULL, 0, "Version of NT Security Descriptor structure", HFILL }},
17576
17577         { &hf_smb_sid_revision,
17578                 { "Revision", "smb.sid.revision", FT_UINT8, BASE_DEC,
17579                 NULL, 0, "Version of SID structure", HFILL }},
17580
17581         { &hf_smb_sid_num_auth,
17582                 { "Num Auth", "smb.sid.num_auth", FT_UINT8, BASE_DEC,
17583                 NULL, 0, "Number of authorities for this SID", HFILL }},
17584
17585         { &hf_smb_acl_revision,
17586                 { "Revision", "smb.acl.revision", FT_UINT16, BASE_DEC,
17587                 NULL, 0, "Version of NT ACL structure", HFILL }},
17588
17589         { &hf_smb_acl_size,
17590                 { "Size", "smb.acl.size", FT_UINT16, BASE_DEC,
17591                 NULL, 0, "Size of NT ACL structure", HFILL }},
17592
17593         { &hf_smb_acl_num_aces,
17594                 { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
17595                 NULL, 0, "Number of ACE structures for this ACL", HFILL }},
17596
17597         { &hf_smb_user_quota_offset,
17598                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
17599                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
17600
17601         { &hf_smb_ace_type,
17602                 { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
17603                 VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
17604
17605         { &hf_smb_ace_size,
17606                 { "Size", "smb.ace.size", FT_UINT16, BASE_DEC,
17607                 NULL, 0, "Size of this ACE", HFILL }},
17608
17609         { &hf_smb_ace_flags_object_inherit,
17610                 { "Object Inherit", "smb.ace.flags.object_inherit", FT_BOOLEAN, 8,
17611                 TFS(&tfs_ace_flags_object_inherit), 0x01, "Will subordinate files inherit this ACE?", HFILL }},
17612
17613         { &hf_smb_ace_flags_container_inherit,
17614                 { "Container Inherit", "smb.ace.flags.container_inherit", FT_BOOLEAN, 8,
17615                 TFS(&tfs_ace_flags_container_inherit), 0x02, "Will subordinate containers inherit this ACE?", HFILL }},
17616
17617         { &hf_smb_ace_flags_non_propagate_inherit,
17618                 { "Non-Propagate Inherit", "smb.ace.flags.non_propagate_inherit", FT_BOOLEAN, 8,
17619                 TFS(&tfs_ace_flags_non_propagate_inherit), 0x04, "Will subordinate object propagate this ACE further?", HFILL }},
17620
17621         { &hf_smb_ace_flags_inherit_only,
17622                 { "Inherit Only", "smb.ace.flags.inherit_only", FT_BOOLEAN, 8,
17623                 TFS(&tfs_ace_flags_inherit_only), 0x08, "Does this ACE apply to the current object?", HFILL }},
17624
17625         { &hf_smb_ace_flags_inherited_ace,
17626                 { "Inherited ACE", "smb.ace.flags.inherited_ace", FT_BOOLEAN, 8,
17627                 TFS(&tfs_ace_flags_inherited_ace), 0x10, "Was this ACE inherited from its parent object?", HFILL }},
17628
17629         { &hf_smb_ace_flags_successful_access,
17630                 { "Audit Successful Accesses", "smb.ace.flags.successful_access", FT_BOOLEAN, 8,
17631                 TFS(&tfs_ace_flags_successful_access), 0x40, "Should successful accesses be audited?", HFILL }},
17632
17633         { &hf_smb_ace_flags_failed_access,
17634                 { "Audit Failed Accesses", "smb.ace.flags.failed_access", FT_BOOLEAN, 8,
17635                 TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
17636
17637         { &hf_smb_sec_desc_type_owner_defaulted,
17638                 { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
17639                 TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
17640
17641         { &hf_smb_sec_desc_type_group_defaulted,
17642                 { "Group Defaulted", "smb.sec_desc.type.group_defaulted", FT_BOOLEAN, 16,
17643                 TFS(&tfs_sec_desc_type_group_defaulted), 0x0002, "Is Group Defaulted?", HFILL }},
17644
17645         { &hf_smb_sec_desc_type_dacl_present,
17646                 { "DACL Present", "smb.sec_desc.type.dacl_present", FT_BOOLEAN, 16,
17647                 TFS(&tfs_sec_desc_type_dacl_present), 0x0004, "Does this SecDesc have DACL present?", HFILL }},
17648
17649         { &hf_smb_sec_desc_type_dacl_defaulted,
17650                 { "DACL Defaulted", "smb.sec_desc.type.dacl_defaulted", FT_BOOLEAN, 16,
17651                 TFS(&tfs_sec_desc_type_dacl_defaulted), 0x0008, "Does this SecDesc have DACL Defaulted?", HFILL }},
17652
17653         { &hf_smb_sec_desc_type_sacl_present,
17654                 { "SACL Present", "smb.sec_desc.type.sacl_present", FT_BOOLEAN, 16,
17655                 TFS(&tfs_sec_desc_type_sacl_present), 0x0010, "Is the SACL present?", HFILL }},
17656
17657         { &hf_smb_sec_desc_type_sacl_defaulted,
17658                 { "SACL Defaulted", "smb.sec_desc.type.sacl_defaulted", FT_BOOLEAN, 16,
17659                 TFS(&tfs_sec_desc_type_sacl_defaulted), 0x0020, "Does this SecDesc have SACL Defaulted?", HFILL }},
17660
17661         { &hf_smb_sec_desc_type_dacl_auto_inherit_req,
17662                 { "DACL Auto Inherit Required", "smb.sec_desc.type.dacl_auto_inherit_req", FT_BOOLEAN, 16,
17663                 TFS(&tfs_sec_desc_type_dacl_auto_inherit_req), 0x0100, "Does this SecDesc have DACL Auto Inherit Required set?", HFILL }},
17664
17665         { &hf_smb_sec_desc_type_sacl_auto_inherit_req,
17666                 { "SACL Auto Inherit Required", "smb.sec_desc.type.sacl_auto_inherit_req", FT_BOOLEAN, 16,
17667                 TFS(&tfs_sec_desc_type_sacl_auto_inherit_req), 0x0200, "Does this SecDesc have SACL Auto Inherit Required set?", HFILL }},
17668
17669         { &hf_smb_sec_desc_type_dacl_auto_inherited,
17670                 { "DACL Auto Inherited", "smb.sec_desc.type.dacl_auto_inherited", FT_BOOLEAN, 16,
17671                 TFS(&tfs_sec_desc_type_dacl_auto_inherited), 0x0400, "Is this DACL auto inherited", HFILL }},
17672
17673         { &hf_smb_sec_desc_type_sacl_auto_inherited,
17674                 { "SACL Auto Inherited", "smb.sec_desc.type.sacl_auto_inherited", FT_BOOLEAN, 16,
17675                 TFS(&tfs_sec_desc_type_sacl_auto_inherited), 0x0800, "Is this SACL auto inherited", HFILL }},
17676
17677         { &hf_smb_sec_desc_type_dacl_protected,
17678                 { "DACL Protected", "smb.sec_desc.type.dacl_protected", FT_BOOLEAN, 16,
17679                 TFS(&tfs_sec_desc_type_dacl_protected), 0x1000, "Is the DACL structure protected?", HFILL }},
17680
17681         { &hf_smb_sec_desc_type_sacl_protected,
17682                 { "SACL Protected", "smb.sec_desc.type.sacl_protected", FT_BOOLEAN, 16,
17683                 TFS(&tfs_sec_desc_type_sacl_protected), 0x2000, "Is the SACL structure protected?", HFILL }},
17684
17685         { &hf_smb_sec_desc_type_self_relative,
17686                 { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
17687                 TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
17688
17689         { &hf_smb_quota_flags_deny_disk,
17690                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
17691                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
17692
17693         { &hf_smb_quota_flags_log_limit,
17694                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
17695                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
17696
17697         { &hf_smb_quota_flags_log_warning,
17698                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
17699                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
17700
17701         { &hf_smb_quota_flags_enabled,
17702                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
17703                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
17704
17705         { &hf_smb_segment_overlap,
17706                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
17707                         "Fragment overlaps with other fragments", HFILL }},
17708
17709         { &hf_smb_segment_overlap_conflict,
17710                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
17711                         "Overlapping fragments contained conflicting data", HFILL }},
17712
17713         { &hf_smb_segment_multiple_tails,
17714                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
17715                         "Several tails were found when defragmenting the packet", HFILL }},
17716
17717         { &hf_smb_segment_too_long_fragment,
17718                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
17719                         "Fragment contained data past end of packet", HFILL }},
17720
17721         { &hf_smb_segment_error,
17722                 { "Defragmentation error", "smb.segment.error", FT_NONE, BASE_NONE, NULL, 0x0,
17723                         "Defragmentation error due to illegal fragments", HFILL }},
17724
17725         { &hf_smb_segment,
17726                 { "SMB Segment", "smb.segment", FT_NONE, BASE_NONE, NULL, 0x0,
17727                         "SMB Segment", HFILL }},
17728
17729         { &hf_smb_segments,
17730                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
17731                         "SMB Segments", HFILL }},
17732         };
17733         static gint *ett[] = {
17734                 &ett_smb,
17735                 &ett_smb_hdr,
17736                 &ett_smb_command,
17737                 &ett_smb_fileattributes,
17738                 &ett_smb_capabilities,
17739                 &ett_smb_aflags,
17740                 &ett_smb_dialect,
17741                 &ett_smb_dialects,
17742                 &ett_smb_mode,
17743                 &ett_smb_rawmode,
17744                 &ett_smb_flags,
17745                 &ett_smb_flags2,
17746                 &ett_smb_desiredaccess,
17747                 &ett_smb_search,
17748                 &ett_smb_file,
17749                 &ett_smb_openfunction,
17750                 &ett_smb_filetype,
17751                 &ett_smb_openaction,
17752                 &ett_smb_writemode,
17753                 &ett_smb_lock_type,
17754                 &ett_smb_ssetupandxaction,
17755                 &ett_smb_optionsup,
17756                 &ett_smb_time_date,
17757                 &ett_smb_move_copy_flags,
17758                 &ett_smb_file_attributes,
17759                 &ett_smb_search_resume_key,
17760                 &ett_smb_search_dir_info,
17761                 &ett_smb_unlocks,
17762                 &ett_smb_unlock,
17763                 &ett_smb_locks,
17764                 &ett_smb_lock,
17765                 &ett_smb_open_flags,
17766                 &ett_smb_ipc_state,
17767                 &ett_smb_open_action,
17768                 &ett_smb_setup_action,
17769                 &ett_smb_connect_flags,
17770                 &ett_smb_connect_support_bits,
17771                 &ett_smb_nt_access_mask,
17772                 &ett_smb_nt_create_bits,
17773                 &ett_smb_nt_create_options,
17774                 &ett_smb_nt_share_access,
17775                 &ett_smb_nt_security_flags,
17776                 &ett_smb_nt_trans_setup,
17777                 &ett_smb_nt_trans_data,
17778                 &ett_smb_nt_trans_param,
17779                 &ett_smb_nt_notify_completion_filter,
17780                 &ett_smb_nt_ioctl_flags,
17781                 &ett_smb_security_information_mask,
17782                 &ett_smb_print_queue_entry,
17783                 &ett_smb_transaction_flags,
17784                 &ett_smb_transaction_params,
17785                 &ett_smb_find_first2_flags,
17786 #if 0
17787                 &ett_smb_ioflag,
17788 #endif
17789                 &ett_smb_transaction_data,
17790                 &ett_smb_stream_info,
17791                 &ett_smb_dfs_referrals,
17792                 &ett_smb_dfs_referral,
17793                 &ett_smb_dfs_referral_flags,
17794                 &ett_smb_get_dfs_flags,
17795                 &ett_smb_ff2_data,
17796                 &ett_smb_device_characteristics,
17797                 &ett_smb_fs_attributes,
17798                 &ett_smb_segments,
17799                 &ett_smb_segment,
17800                 &ett_smb_sec_desc,
17801                 &ett_smb_sid,
17802                 &ett_smb_acl,
17803                 &ett_smb_ace,
17804                 &ett_smb_ace_flags,
17805                 &ett_smb_sec_desc_type,
17806                 &ett_smb_quotaflags,
17807                 &ett_smb_gssapi,
17808                 &ett_smb_mac_support_flags,
17809         };
17810         module_t *smb_module;
17811
17812         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
17813             "SMB", "smb");
17814         proto_register_subtree_array(ett, array_length(ett));
17815         proto_register_field_array(proto_smb, hf, array_length(hf));
17816         register_init_routine(&smb_init_protocol);
17817         smb_module = prefs_register_protocol(proto_smb, NULL);
17818         prefs_register_bool_preference(smb_module, "trans_reassembly",
17819                 "Reassemble SMB Transaction payload",
17820                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
17821                 &smb_trans_reassembly);
17822         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
17823                 "Reassemble DCERPC over SMB",
17824                 "Whether the dissector should reassemble DCERPC over SMB commands",
17825                 &smb_dcerpc_reassembly);
17826         register_init_routine(smb_trans_reassembly_init);
17827         register_init_routine(smb_dcerpc_reassembly_init);
17828 }
17829
17830 void
17831 proto_reg_handoff_smb(void)
17832 {
17833         heur_dissector_add("netbios", dissect_smb, proto_smb);
17834         gssapi_handle = find_dissector("gssapi");
17835 }