Update Kari Tiirikainen's e-mail address.
[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.250 2002/04/27 21:23:48 guy Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  *
12  * Copied from packet-pop.c
13  * 
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  * 
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  * 
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <stdio.h>
34
35 #ifdef HAVE_SYS_TYPES_H
36 # include <sys/types.h>
37 #endif
38
39 #ifdef HAVE_NETINET_IN_H
40 # include <netinet/in.h>
41 #endif
42
43 #include <time.h>
44 #include <string.h>
45 #include <glib.h>
46 #include <ctype.h>
47 #include <epan/packet.h>
48 #include <epan/conversation.h>
49 #include "smb.h"
50 #include "alignment.h"
51 #include <epan/strutil.h>
52 #include "prefs.h"
53 #include "reassemble.h"
54
55 #include "packet-smb-mailslot.h"
56 #include "packet-smb-pipe.h"
57
58 /*
59  * Various specifications and documents about SMB can be found in
60  *
61  *      ftp://ftp.microsoft.com/developr/drg/CIFS/
62  *
63  * and a CIFS draft from the Storage Networking Industry Association
64  * can be found on a link from the page at
65  *
66  *      http://www.snia.org/English/Work_Groups/NAS/CIFS/WG_CIFS_Docs.html
67  *
68  * (it supercedes the document at
69  *
70  *      ftp://ftp.microsoft.com/developr/drg/CIFS/draft-leach-cifs-v1-spec-01.txt
71  *
72  * ).
73  *
74  * There are also some Open Group publications documenting CIFS for sale;
75  * catalog entries for them are at:
76  *
77  *      http://www.opengroup.org/products/publications/catalog/c209.htm
78  *
79  *      http://www.opengroup.org/products/publications/catalog/c195.htm
80  *
81  * The document "NT LAN Manager SMB File Sharing Protocol Extensions"
82  * can be found at
83  *
84  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
85  *
86  * (or, presumably a similar path under the Samba mirrors).  As the
87  * ".doc" indicates, it's a Word document.  Some of the specs from the
88  * Microsoft FTP site can be found in the
89  *
90  *      http://www.samba.org/samba/ftp/specs/
91  *
92  * directory as well.
93  *
94  * Beware - these specs may have errors.
95  */
96 static int proto_smb = -1;
97 static int hf_smb_cmd = -1;
98 static int hf_smb_pid = -1;
99 static int hf_smb_tid = -1;
100 static int hf_smb_uid = -1;
101 static int hf_smb_mid = -1;
102 static int hf_smb_response_to = -1;
103 static int hf_smb_response_in = -1;
104 static int hf_smb_continuation_to = -1;
105 static int hf_smb_nt_status = -1;
106 static int hf_smb_error_class = -1;
107 static int hf_smb_error_code = -1;
108 static int hf_smb_reserved = -1;
109 static int hf_smb_flags_lock = -1;
110 static int hf_smb_flags_receive_buffer = -1;
111 static int hf_smb_flags_caseless = -1;
112 static int hf_smb_flags_canon = -1;
113 static int hf_smb_flags_oplock = -1;
114 static int hf_smb_flags_notify = -1;
115 static int hf_smb_flags_response = -1;
116 static int hf_smb_flags2_long_names_allowed = -1;
117 static int hf_smb_flags2_ea = -1;
118 static int hf_smb_flags2_sec_sig = -1;
119 static int hf_smb_flags2_long_names_used = -1;
120 static int hf_smb_flags2_esn = -1;
121 static int hf_smb_flags2_dfs = -1;
122 static int hf_smb_flags2_roe = -1;
123 static int hf_smb_flags2_nt_error = -1;
124 static int hf_smb_flags2_string = -1;
125 static int hf_smb_word_count = -1;
126 static int hf_smb_byte_count = -1;
127 static int hf_smb_buffer_format = -1;
128 static int hf_smb_dialect_name = -1;
129 static int hf_smb_dialect_index = -1;
130 static int hf_smb_max_trans_buf_size = -1;
131 static int hf_smb_max_mpx_count = -1;
132 static int hf_smb_max_vcs_num = -1;
133 static int hf_smb_session_key = -1;
134 static int hf_smb_server_timezone = -1;
135 static int hf_smb_encryption_key_length = -1;
136 static int hf_smb_encryption_key = -1;
137 static int hf_smb_primary_domain = -1;
138 static int hf_smb_max_raw_buf_size = -1;
139 static int hf_smb_server_guid = -1;
140 static int hf_smb_security_blob_len = -1;
141 static int hf_smb_security_blob = -1;
142 static int hf_smb_sm_mode16 = -1;
143 static int hf_smb_sm_password16 = -1;
144 static int hf_smb_sm_mode = -1;
145 static int hf_smb_sm_password = -1;
146 static int hf_smb_sm_signatures = -1;
147 static int hf_smb_sm_sig_required = -1;
148 static int hf_smb_rm_read = -1;
149 static int hf_smb_rm_write = -1;
150 static int hf_smb_server_date_time = -1;
151 static int hf_smb_server_smb_date = -1;
152 static int hf_smb_server_smb_time = -1;
153 static int hf_smb_server_cap_raw_mode = -1;
154 static int hf_smb_server_cap_mpx_mode = -1;
155 static int hf_smb_server_cap_unicode = -1;
156 static int hf_smb_server_cap_large_files = -1;
157 static int hf_smb_server_cap_nt_smbs = -1;
158 static int hf_smb_server_cap_rpc_remote_apis = -1;
159 static int hf_smb_server_cap_nt_status = -1;
160 static int hf_smb_server_cap_level_ii_oplocks = -1;
161 static int hf_smb_server_cap_lock_and_read = -1;
162 static int hf_smb_server_cap_nt_find = -1;
163 static int hf_smb_server_cap_dfs = -1;
164 static int hf_smb_server_cap_infolevel_passthru = -1;
165 static int hf_smb_server_cap_large_readx = -1;
166 static int hf_smb_server_cap_large_writex = -1;
167 static int hf_smb_server_cap_unix = -1;
168 static int hf_smb_server_cap_reserved = -1;
169 static int hf_smb_server_cap_bulk_transfer = -1;
170 static int hf_smb_server_cap_compressed_data = -1;
171 static int hf_smb_server_cap_extended_security = -1;
172 static int hf_smb_system_time = -1;
173 static int hf_smb_unknown = -1;
174 static int hf_smb_dir_name = -1;
175 static int hf_smb_echo_count = -1;
176 static int hf_smb_echo_data = -1;
177 static int hf_smb_echo_seq_num = -1;
178 static int hf_smb_max_buf_size = -1;
179 static int hf_smb_password = -1;
180 static int hf_smb_password_len = -1;
181 static int hf_smb_ansi_password = -1;
182 static int hf_smb_ansi_password_len = -1;
183 static int hf_smb_unicode_password = -1;
184 static int hf_smb_unicode_password_len = -1;
185 static int hf_smb_path = -1;
186 static int hf_smb_service = -1;
187 static int hf_smb_move_flags_file = -1;
188 static int hf_smb_move_flags_dir = -1;
189 static int hf_smb_move_flags_verify = -1;
190 static int hf_smb_move_files_moved = -1;
191 static int hf_smb_count = -1;
192 static int hf_smb_file_name = -1;
193 static int hf_smb_open_function_open = -1;
194 static int hf_smb_open_function_create = -1;
195 static int hf_smb_fid = -1;
196 static int hf_smb_file_attr_read_only_16bit = -1;
197 static int hf_smb_file_attr_read_only_8bit = -1;
198 static int hf_smb_file_attr_hidden_16bit = -1;
199 static int hf_smb_file_attr_hidden_8bit = -1;
200 static int hf_smb_file_attr_system_16bit = -1;
201 static int hf_smb_file_attr_system_8bit = -1;
202 static int hf_smb_file_attr_volume_16bit = -1;
203 static int hf_smb_file_attr_volume_8bit = -1;
204 static int hf_smb_file_attr_directory_16bit = -1;
205 static int hf_smb_file_attr_directory_8bit = -1;
206 static int hf_smb_file_attr_archive_16bit = -1;
207 static int hf_smb_file_attr_archive_8bit = -1;
208 static int hf_smb_file_attr_device = -1;
209 static int hf_smb_file_attr_normal = -1;
210 static int hf_smb_file_attr_temporary = -1;
211 static int hf_smb_file_attr_sparse = -1;
212 static int hf_smb_file_attr_reparse = -1;
213 static int hf_smb_file_attr_compressed = -1;
214 static int hf_smb_file_attr_offline = -1;
215 static int hf_smb_file_attr_not_content_indexed = -1;
216 static int hf_smb_file_attr_encrypted = -1;
217 static int hf_smb_file_size = -1;
218 static int hf_smb_search_attribute_read_only = -1;
219 static int hf_smb_search_attribute_hidden = -1;
220 static int hf_smb_search_attribute_system = -1;
221 static int hf_smb_search_attribute_volume = -1;
222 static int hf_smb_search_attribute_directory = -1;
223 static int hf_smb_search_attribute_archive = -1;
224 static int hf_smb_access_mode = -1;
225 static int hf_smb_access_sharing = -1;
226 static int hf_smb_access_locality = -1;
227 static int hf_smb_access_caching = -1;
228 static int hf_smb_access_writetru = -1;
229 static int hf_smb_create_time = -1;
230 static int hf_smb_create_dos_date = -1;
231 static int hf_smb_create_dos_time = -1;
232 static int hf_smb_last_write_time = -1;
233 static int hf_smb_last_write_dos_date = -1;
234 static int hf_smb_last_write_dos_time = -1;
235 static int hf_smb_access_time = -1;
236 static int hf_smb_access_dos_date = -1;
237 static int hf_smb_access_dos_time = -1;
238 static int hf_smb_old_file_name = -1;
239 static int hf_smb_offset = -1;
240 static int hf_smb_remaining = -1;
241 static int hf_smb_padding = -1;
242 static int hf_smb_file_data = -1;
243 static int hf_smb_total_data_len = -1;
244 static int hf_smb_data_len = -1;
245 static int hf_smb_seek_mode = -1;
246 static int hf_smb_data_size = -1;
247 static int hf_smb_alloc_size = -1;
248 static int hf_smb_alloc_size64 = -1;
249 static int hf_smb_max_count = -1;
250 static int hf_smb_min_count = -1;
251 static int hf_smb_timeout = -1;
252 static int hf_smb_high_offset = -1;
253 static int hf_smb_units = -1;
254 static int hf_smb_bpu = -1;
255 static int hf_smb_blocksize = -1;
256 static int hf_smb_freeunits = -1;
257 static int hf_smb_data_offset = -1;
258 static int hf_smb_dcm = -1;
259 static int hf_smb_request_mask = -1;
260 static int hf_smb_response_mask = -1;
261 static int hf_smb_sid = -1;
262 static int hf_smb_write_mode_write_through = -1;
263 static int hf_smb_write_mode_return_remaining = -1;
264 static int hf_smb_write_mode_raw = -1;
265 static int hf_smb_write_mode_message_start = -1;
266 static int hf_smb_write_mode_connectionless = -1;
267 static int hf_smb_resume_key_len = -1;
268 static int hf_smb_resume_server_cookie = -1;
269 static int hf_smb_resume_client_cookie = -1;
270 static int hf_smb_andxoffset = -1;
271 static int hf_smb_lock_type_large = -1;
272 static int hf_smb_lock_type_cancel = -1;
273 static int hf_smb_lock_type_change = -1;
274 static int hf_smb_lock_type_oplock = -1;
275 static int hf_smb_lock_type_shared = -1;
276 static int hf_smb_locking_ol = -1;
277 static int hf_smb_number_of_locks = -1;
278 static int hf_smb_number_of_unlocks = -1;
279 static int hf_smb_lock_long_offset = -1;
280 static int hf_smb_lock_long_length = -1;
281 static int hf_smb_file_type = -1;
282 static int hf_smb_ipc_state_nonblocking = -1;
283 static int hf_smb_ipc_state_endpoint = -1;
284 static int hf_smb_ipc_state_pipe_type = -1;
285 static int hf_smb_ipc_state_read_mode = -1;
286 static int hf_smb_ipc_state_icount = -1;
287 static int hf_smb_server_fid = -1;
288 static int hf_smb_open_flags_add_info = -1;
289 static int hf_smb_open_flags_ex_oplock = -1;
290 static int hf_smb_open_flags_batch_oplock = -1;
291 static int hf_smb_open_flags_ealen = -1;
292 static int hf_smb_open_action_open = -1;
293 static int hf_smb_open_action_lock = -1;
294 static int hf_smb_vc_num = -1;
295 static int hf_smb_account = -1;
296 static int hf_smb_os = -1;
297 static int hf_smb_lanman = -1;
298 static int hf_smb_setup_action_guest = -1;
299 static int hf_smb_fs = -1;
300 static int hf_smb_connect_flags_dtid = -1;
301 static int hf_smb_connect_support_search = -1;
302 static int hf_smb_connect_support_in_dfs = -1;
303 static int hf_smb_max_setup_count = -1;
304 static int hf_smb_total_param_count = -1;
305 static int hf_smb_total_data_count = -1;
306 static int hf_smb_max_param_count = -1;
307 static int hf_smb_max_data_count = -1;
308 static int hf_smb_param_disp16 = -1;
309 static int hf_smb_param_count16 = -1;
310 static int hf_smb_param_offset16 = -1;
311 static int hf_smb_param_disp32 = -1;
312 static int hf_smb_param_count32 = -1;
313 static int hf_smb_param_offset32 = -1;
314 static int hf_smb_data_disp16 = -1;
315 static int hf_smb_data_count16 = -1;
316 static int hf_smb_data_offset16 = -1;
317 static int hf_smb_data_disp32 = -1;
318 static int hf_smb_data_count32 = -1;
319 static int hf_smb_data_offset32 = -1;
320 static int hf_smb_setup_count = -1;
321 static int hf_smb_nt_trans_subcmd = -1;
322 static int hf_smb_nt_ioctl_function_code = -1;
323 static int hf_smb_nt_ioctl_isfsctl = -1;
324 static int hf_smb_nt_ioctl_flags_root_handle = -1;
325 static int hf_smb_nt_ioctl_data = -1;
326 static int hf_smb_nt_security_information = -1;
327 static int hf_smb_nt_notify_action = -1;
328 static int hf_smb_nt_notify_watch_tree = -1;
329 static int hf_smb_nt_notify_stream_write = -1;
330 static int hf_smb_nt_notify_stream_size = -1;
331 static int hf_smb_nt_notify_stream_name = -1;
332 static int hf_smb_nt_notify_security = -1;
333 static int hf_smb_nt_notify_ea = -1;
334 static int hf_smb_nt_notify_creation = -1;
335 static int hf_smb_nt_notify_last_access = -1;
336 static int hf_smb_nt_notify_last_write = -1;
337 static int hf_smb_nt_notify_size = -1;
338 static int hf_smb_nt_notify_attributes = -1;
339 static int hf_smb_nt_notify_dir_name = -1;
340 static int hf_smb_nt_notify_file_name = -1;
341 static int hf_smb_root_dir_fid = -1;
342 static int hf_smb_nt_create_disposition = -1;
343 static int hf_smb_sd_length = -1;
344 static int hf_smb_ea_length = -1;
345 static int hf_smb_file_name_len = -1;
346 static int hf_smb_nt_impersonation_level = -1;
347 static int hf_smb_nt_security_flags_context_tracking = -1;
348 static int hf_smb_nt_security_flags_effective_only = -1;
349 static int hf_smb_nt_access_mask_generic_read = -1;
350 static int hf_smb_nt_access_mask_generic_write = -1;
351 static int hf_smb_nt_access_mask_generic_execute = -1;
352 static int hf_smb_nt_access_mask_generic_all = -1;
353 static int hf_smb_nt_access_mask_maximum_allowed = -1;
354 static int hf_smb_nt_access_mask_system_security = -1;
355 static int hf_smb_nt_access_mask_synchronize = -1;
356 static int hf_smb_nt_access_mask_write_owner = -1;
357 static int hf_smb_nt_access_mask_write_dac = -1;
358 static int hf_smb_nt_access_mask_read_control = -1;
359 static int hf_smb_nt_access_mask_delete = -1;
360 static int hf_smb_nt_access_mask_write_attributes = -1;
361 static int hf_smb_nt_access_mask_read_attributes = -1;
362 static int hf_smb_nt_access_mask_delete_child = -1;
363 static int hf_smb_nt_access_mask_execute = -1;
364 static int hf_smb_nt_access_mask_write_ea = -1;
365 static int hf_smb_nt_access_mask_read_ea = -1;
366 static int hf_smb_nt_access_mask_append = -1;
367 static int hf_smb_nt_access_mask_write = -1;
368 static int hf_smb_nt_access_mask_read = -1;
369 static int hf_smb_nt_create_bits_oplock = -1;
370 static int hf_smb_nt_create_bits_boplock = -1;
371 static int hf_smb_nt_create_bits_dir = -1;
372 static int hf_smb_nt_create_options_directory_file = -1;
373 static int hf_smb_nt_create_options_write_through = -1;
374 static int hf_smb_nt_create_options_sequential_only = -1;
375 static int hf_smb_nt_create_options_sync_io_alert = -1;
376 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
377 static int hf_smb_nt_create_options_non_directory_file = -1;
378 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
379 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
380 static int hf_smb_nt_create_options_random_access = -1;
381 static int hf_smb_nt_create_options_delete_on_close = -1;
382 static int hf_smb_nt_share_access_read = -1;
383 static int hf_smb_nt_share_access_write = -1;
384 static int hf_smb_nt_share_access_delete = -1;
385 static int hf_smb_file_eattr_read_only = -1;
386 static int hf_smb_file_eattr_hidden = -1;
387 static int hf_smb_file_eattr_system = -1;
388 static int hf_smb_file_eattr_volume = -1;
389 static int hf_smb_file_eattr_directory = -1;
390 static int hf_smb_file_eattr_archive = -1;
391 static int hf_smb_file_eattr_device = -1;
392 static int hf_smb_file_eattr_normal = -1;
393 static int hf_smb_file_eattr_temporary = -1;
394 static int hf_smb_file_eattr_sparse = -1;
395 static int hf_smb_file_eattr_reparse = -1;
396 static int hf_smb_file_eattr_compressed = -1;
397 static int hf_smb_file_eattr_offline = -1;
398 static int hf_smb_file_eattr_not_content_indexed = -1;
399 static int hf_smb_file_eattr_encrypted = -1;
400 static int hf_smb_file_eattr_write_through = -1;
401 static int hf_smb_file_eattr_no_buffering = -1;
402 static int hf_smb_file_eattr_random_access = -1;
403 static int hf_smb_file_eattr_sequential_scan = -1;
404 static int hf_smb_file_eattr_delete_on_close = -1;
405 static int hf_smb_file_eattr_backup_semantics = -1;
406 static int hf_smb_file_eattr_posix_semantics = -1;
407 static int hf_smb_sec_desc_len = -1;
408 static int hf_smb_sec_desc_revision = -1;
409 static int hf_smb_sec_desc_type_owner_defaulted = -1;
410 static int hf_smb_sec_desc_type_group_defaulted = -1;
411 static int hf_smb_sec_desc_type_dacl_present = -1;
412 static int hf_smb_sec_desc_type_dacl_defaulted = -1;
413 static int hf_smb_sec_desc_type_sacl_present = -1;
414 static int hf_smb_sec_desc_type_sacl_defaulted = -1;
415 static int hf_smb_sec_desc_type_dacl_auto_inherit_req = -1;
416 static int hf_smb_sec_desc_type_sacl_auto_inherit_req = -1;
417 static int hf_smb_sec_desc_type_dacl_auto_inherited = -1;
418 static int hf_smb_sec_desc_type_sacl_auto_inherited = -1;
419 static int hf_smb_sec_desc_type_dacl_protected = -1;
420 static int hf_smb_sec_desc_type_sacl_protected = -1;
421 static int hf_smb_sec_desc_type_self_relative = -1;
422 static int hf_smb_sid_revision = -1;
423 static int hf_smb_sid_num_auth = -1;
424 static int hf_smb_acl_revision = -1;
425 static int hf_smb_acl_size = -1;
426 static int hf_smb_acl_num_aces = -1;
427 static int hf_smb_ace_type = -1;
428 static int hf_smb_ace_size = -1;
429 static int hf_smb_ace_flags_object_inherit = -1;
430 static int hf_smb_ace_flags_container_inherit = -1;
431 static int hf_smb_ace_flags_non_propagate_inherit = -1;
432 static int hf_smb_ace_flags_inherit_only = -1;
433 static int hf_smb_ace_flags_inherited_ace = -1;
434 static int hf_smb_ace_flags_successful_access = -1;
435 static int hf_smb_ace_flags_failed_access = -1;
436 static int hf_smb_nt_qsd_owner = -1;
437 static int hf_smb_nt_qsd_group = -1;
438 static int hf_smb_nt_qsd_dacl = -1;
439 static int hf_smb_nt_qsd_sacl = -1;
440 static int hf_smb_extended_attributes = -1;
441 static int hf_smb_oplock_level = -1;
442 static int hf_smb_create_action = -1;
443 static int hf_smb_ea_error_offset = -1;
444 static int hf_smb_end_of_file = -1;
445 static int hf_smb_device_type = -1;
446 static int hf_smb_is_directory = -1;
447 static int hf_smb_next_entry_offset = -1;
448 static int hf_smb_change_time = -1;
449 static int hf_smb_setup_len = -1;
450 static int hf_smb_print_mode = -1;
451 static int hf_smb_print_identifier = -1;
452 static int hf_smb_restart_index = -1;
453 static int hf_smb_print_queue_date = -1;
454 static int hf_smb_print_queue_dos_date = -1;
455 static int hf_smb_print_queue_dos_time = -1;
456 static int hf_smb_print_status = -1;
457 static int hf_smb_print_spool_file_number = -1;
458 static int hf_smb_print_spool_file_size = -1;
459 static int hf_smb_print_spool_file_name = -1;
460 static int hf_smb_start_index = -1;
461 static int hf_smb_cancel_to = -1;
462 static int hf_smb_trans2_subcmd = -1;
463 static int hf_smb_trans_name = -1;
464 static int hf_smb_transaction_flags_dtid = -1;
465 static int hf_smb_transaction_flags_owt = -1;
466 static int hf_smb_search_count = -1;
467 static int hf_smb_search_pattern = -1;
468 static int hf_smb_ff2_backup = -1;
469 static int hf_smb_ff2_continue = -1;
470 static int hf_smb_ff2_resume = -1;
471 static int hf_smb_ff2_close_eos = -1;
472 static int hf_smb_ff2_close = -1;
473 static int hf_smb_ff2_information_level = -1;
474 static int hf_smb_qpi_loi = -1;
475 static int hf_smb_storage_type = -1;
476 static int hf_smb_resume = -1;
477 static int hf_smb_max_referral_level = -1;
478 static int hf_smb_qfsi_information_level = -1;
479 static int hf_smb_ea_size = -1;
480 static int hf_smb_list_length = -1;
481 static int hf_smb_number_of_links = -1;
482 static int hf_smb_delete_pending = -1;
483 static int hf_smb_index_number = -1;
484 static int hf_smb_current_offset = -1;
485 static int hf_smb_t2_alignment = -1;
486 static int hf_smb_t2_stream_name_length = -1;
487 static int hf_smb_t2_stream_size = -1;
488 static int hf_smb_t2_stream_name = -1;
489 static int hf_smb_t2_compressed_file_size = -1;
490 static int hf_smb_t2_compressed_format = -1;
491 static int hf_smb_t2_compressed_unit_shift = -1;
492 static int hf_smb_t2_compressed_chunk_shift = -1;
493 static int hf_smb_t2_compressed_cluster_shift = -1;
494 static int hf_smb_dfs_path_consumed = -1;
495 static int hf_smb_dfs_num_referrals = -1;
496 static int hf_smb_get_dfs_server_hold_storage = -1;
497 static int hf_smb_get_dfs_fielding = -1;
498 static int hf_smb_dfs_referral_version = -1;
499 static int hf_smb_dfs_referral_size = -1;
500 static int hf_smb_dfs_referral_server_type = -1;
501 static int hf_smb_dfs_referral_flags_strip = -1;
502 static int hf_smb_dfs_referral_node_offset = -1;
503 static int hf_smb_dfs_referral_node = -1;
504 static int hf_smb_dfs_referral_proximity = -1;
505 static int hf_smb_dfs_referral_ttl = -1;
506 static int hf_smb_dfs_referral_path_offset = -1;
507 static int hf_smb_dfs_referral_path = -1;
508 static int hf_smb_dfs_referral_alt_path_offset = -1;
509 static int hf_smb_dfs_referral_alt_path = -1;
510 static int hf_smb_end_of_search = -1;
511 static int hf_smb_last_name_offset = -1;
512 static int hf_smb_file_index = -1;
513 static int hf_smb_short_file_name = -1;
514 static int hf_smb_short_file_name_len = -1;
515 static int hf_smb_fs_id = -1;
516 static int hf_smb_sector_unit = -1;
517 static int hf_smb_fs_units = -1;
518 static int hf_smb_fs_sector = -1;
519 static int hf_smb_avail_units = -1;
520 static int hf_smb_volume_serial_num = -1;
521 static int hf_smb_volume_label_len = -1;
522 static int hf_smb_volume_label = -1;
523 static int hf_smb_free_alloc_units64 = -1;
524 static int hf_smb_max_name_len = -1;
525 static int hf_smb_fs_name_len = -1;
526 static int hf_smb_fs_name = -1;
527 static int hf_smb_device_char_removable = -1;
528 static int hf_smb_device_char_read_only = -1;
529 static int hf_smb_device_char_floppy = -1;
530 static int hf_smb_device_char_write_once = -1;
531 static int hf_smb_device_char_remote = -1;
532 static int hf_smb_device_char_mounted = -1;
533 static int hf_smb_device_char_virtual = -1;
534 static int hf_smb_fs_attr_css = -1;
535 static int hf_smb_fs_attr_cpn = -1;
536 static int hf_smb_fs_attr_pacls = -1;
537 static int hf_smb_fs_attr_fc = -1;
538 static int hf_smb_fs_attr_vq = -1;
539 static int hf_smb_fs_attr_dim = -1;
540 static int hf_smb_fs_attr_vic = -1;
541 static int hf_smb_quota_flags_enabled = -1;
542 static int hf_smb_quota_flags_deny_disk = -1;
543 static int hf_smb_quota_flags_log_limit = -1;
544 static int hf_smb_quota_flags_log_warning = -1;
545 static int hf_smb_soft_quota_limit = -1;
546 static int hf_smb_hard_quota_limit = -1;
547 static int hf_smb_user_quota_used = -1;
548 static int hf_smb_user_quota_offset = -1;
549 static int hf_smb_nt_rename_level = -1;
550 static int hf_smb_cluster_count = -1;
551
552 static gint ett_smb = -1;
553 static gint ett_smb_hdr = -1;
554 static gint ett_smb_command = -1;
555 static gint ett_smb_fileattributes = -1;
556 static gint ett_smb_capabilities = -1;
557 static gint ett_smb_aflags = -1;
558 static gint ett_smb_dialect = -1;
559 static gint ett_smb_dialects = -1;
560 static gint ett_smb_mode = -1;
561 static gint ett_smb_rawmode = -1;
562 static gint ett_smb_flags = -1;
563 static gint ett_smb_flags2 = -1;
564 static gint ett_smb_desiredaccess = -1;
565 static gint ett_smb_search = -1;
566 static gint ett_smb_file = -1;
567 static gint ett_smb_openfunction = -1;
568 static gint ett_smb_filetype = -1;
569 static gint ett_smb_openaction = -1;
570 static gint ett_smb_writemode = -1;
571 static gint ett_smb_lock_type = -1;
572 static gint ett_smb_ssetupandxaction = -1;
573 static gint ett_smb_optionsup = -1;
574 static gint ett_smb_time_date = -1;
575 static gint ett_smb_move_flags = -1;
576 static gint ett_smb_file_attributes = -1;
577 static gint ett_smb_search_resume_key = -1;
578 static gint ett_smb_search_dir_info = -1;
579 static gint ett_smb_unlocks = -1;
580 static gint ett_smb_unlock = -1;
581 static gint ett_smb_locks = -1;
582 static gint ett_smb_lock = -1;
583 static gint ett_smb_open_flags = -1;
584 static gint ett_smb_ipc_state = -1;
585 static gint ett_smb_open_action = -1;
586 static gint ett_smb_setup_action = -1;
587 static gint ett_smb_connect_flags = -1;
588 static gint ett_smb_connect_support_bits = -1;
589 static gint ett_smb_nt_access_mask = -1;
590 static gint ett_smb_nt_create_bits = -1;
591 static gint ett_smb_nt_create_options = -1;
592 static gint ett_smb_nt_share_access = -1;
593 static gint ett_smb_nt_security_flags = -1;
594 static gint ett_smb_nt_trans_setup = -1;
595 static gint ett_smb_nt_trans_data = -1;
596 static gint ett_smb_nt_trans_param = -1;
597 static gint ett_smb_nt_notify_completion_filter = -1;
598 static gint ett_smb_nt_ioctl_flags = -1;
599 static gint ett_smb_security_information_mask = -1;
600 static gint ett_smb_print_queue_entry = -1;
601 static gint ett_smb_transaction_flags = -1;
602 static gint ett_smb_transaction_params = -1;
603 static gint ett_smb_find_first2_flags = -1;
604 static gint ett_smb_transaction_data = -1;
605 static gint ett_smb_stream_info = -1;
606 static gint ett_smb_dfs_referrals = -1;
607 static gint ett_smb_dfs_referral = -1;
608 static gint ett_smb_dfs_referral_flags = -1;
609 static gint ett_smb_get_dfs_flags = -1;
610 static gint ett_smb_ff2_data = -1;
611 static gint ett_smb_device_characteristics = -1;
612 static gint ett_smb_fs_attributes = -1;
613 static gint ett_smb_segments = -1;
614 static gint ett_smb_sec_desc = -1;
615 static gint ett_smb_sid = -1;
616 static gint ett_smb_acl = -1;
617 static gint ett_smb_ace = -1;
618 static gint ett_smb_ace_flags = -1;
619 static gint ett_smb_sec_desc_type = -1;
620 static gint ett_smb_quotaflags = -1;
621
622 proto_tree *top_tree=NULL;     /* ugly */
623
624 static char *decode_smb_name(unsigned char);
625 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, guint8 cmd);
626 static const gchar *get_unicode_or_ascii_string(tvbuff_t *tvb,
627     int *offsetp, packet_info *pinfo, int *len, gboolean nopad,
628     gboolean exactlen, guint16 *bcp);
629
630 /*
631  * Macros for use in the main dissector routines for an SMB.
632  */
633
634 #define WORD_COUNT      \
635         /* Word Count */                                \
636         wc = tvb_get_guint8(tvb, offset);               \
637         proto_tree_add_uint(tree, hf_smb_word_count,    \
638                 tvb, offset, 1, wc);                    \
639         offset += 1;                                    \
640         if(wc==0) goto bytecount;
641
642 #define BYTE_COUNT      \
643         bytecount:                                      \
644         bc = tvb_get_letohs(tvb, offset);               \
645         proto_tree_add_uint(tree, hf_smb_byte_count,    \
646                         tvb, offset, 2, bc);            \
647         offset += 2;                                    \
648         if(bc==0) goto endofcommand;
649
650 #define CHECK_BYTE_COUNT(len)   \
651         if (bc < len) goto endofcommand;
652
653 #define COUNT_BYTES(len)   {\
654         int tmp;            \
655         tmp=len;            \
656         offset += tmp;      \
657         bc -= tmp;          \
658         }
659
660 #define END_OF_SMB      \
661         if (bc != 0) { \
662                 proto_tree_add_text(tree, tvb, offset, bc, \
663                     "Extra byte parameters");           \
664                 offset += bc;                           \
665         }                                               \
666         endofcommand:
667
668 /*
669  * Macros for use in routines called by them.
670  */
671 #define CHECK_BYTE_COUNT_SUBR(len)      \
672         if (*bcp < len) {               \
673                 *trunc = TRUE;          \
674                 return offset;          \
675         }
676
677 #define CHECK_STRING_SUBR(fn)   \
678         if (fn == NULL) {       \
679                 *trunc = TRUE;  \
680                 return offset;  \
681         }
682
683 #define COUNT_BYTES_SUBR(len)   \
684         offset += len;          \
685         *bcp -= len;
686
687 /*
688  * Macros for use when dissecting transaction parameters and data
689  */
690 #define CHECK_BYTE_COUNT_TRANS(len)     \
691         if (bc < len) return offset;
692
693 #define CHECK_STRING_TRANS(fn)  \
694         if (fn == NULL) return offset;
695
696 #define COUNT_BYTES_TRANS(len)  \
697         offset += len;          \
698         bc -= len;
699
700 /*
701  * Macros for use in subrroutines dissecting transaction parameters or data
702  */
703 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
704         if (*bcp < len) return offset;
705
706 #define CHECK_STRING_TRANS_SUBR(fn)     \
707         if (fn == NULL) return offset;
708
709 #define COUNT_BYTES_TRANS_SUBR(len)     \
710         offset += len;                  \
711         *bcp -= len;
712
713
714 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
715    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
716    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
717 static gboolean smb_trans_reassembly = FALSE;
718 gboolean smb_dcerpc_reassembly = FALSE;
719
720 static GHashTable *smb_trans_fragment_table = NULL;
721 GHashTable *dcerpc_fragment_table = NULL;
722
723 static void
724 smb_trans_reassembly_init(void)
725 {
726         fragment_table_init(&smb_trans_fragment_table);
727 }
728 static void
729 smb_dcerpc_reassembly_init(void)
730 {
731         fragment_table_init(&dcerpc_fragment_table);
732 }
733
734
735 static fragment_data *
736 smb_trans_defragment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
737                      int offset, int count, int pos, int totlen)
738 {
739         fragment_data *fd_head=NULL;
740         smb_info_t *si;
741         int more_frags;
742
743         more_frags=totlen>(pos+count);
744
745         si = (smb_info_t *)pinfo->private_data;
746         if (si->sip == NULL) {
747                 /*
748                  * We don't have the frame number of the request.
749                  *
750                  * XXX - is there truly nothing we can do here?
751                  * Can we not separately keep track of the original
752                  * transaction and its continuations, as we did
753                  * at one time?
754                  *
755                  * It is probably not much point in even trying to do something here
756                  * if we have never seen the initial request. Without the initial 
757                  * request we probably miss all parameters and the begining of data
758                  * so we cant even call a subdissector since we can not determine
759                  * which type of transaction call this is.
760                  */
761                 return NULL;
762         }
763
764         if(!pinfo->fd->flags.visited){
765                 fd_head = fragment_add(tvb, offset, pinfo,
766                                        si->sip->frame_req, smb_trans_fragment_table,
767                                        pos, count, more_frags);
768         } else {
769                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
770         }
771
772         /* we only show the defragmented packet for the first fragment,
773            or else we might end up with dissecting one HUGE transaction PDU
774            a LOT of times. (first fragment is the only one containing the setup
775            bytes)
776            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction 
777            SMBs. Takes a LOT of time dissecting and is not fun.
778         */
779         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
780                 return fd_head;
781         } else {
782                 return NULL;
783         }
784 }
785                 
786
787
788
789
790 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
791    These variables and functions are used to match
792    responses with calls
793    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
794 /*
795  * The information we need to save about a request in order to show the
796  * frame number of the request in the dissection of the reply.
797  */
798 typedef struct  {
799         guint32 frame;
800         guint32 pid_mid;
801 } smb_saved_info_key_t;
802
803 static GMemChunk *smb_saved_info_key_chunk = NULL;
804 static GMemChunk *smb_saved_info_chunk = NULL;
805 static int smb_saved_info_init_count = 200;
806
807 /* unmatched smb_saved_info structures.
808    For unmatched smb_saved_info structures we store the smb_saved_info
809    structure using the MID and the PID as the key.
810
811    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
812    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
813    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
814 */
815 static gint
816 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
817 {
818         register guint32 key1 = (guint32)k1;
819         register guint32 key2 = (guint32)k2;
820         return key1==key2;
821 }
822 static guint
823 smb_saved_info_hash_unmatched(gconstpointer k)
824 {
825         register guint32 key = (guint32)k;
826         return key;
827 }
828
829 /* matched smb_saved_info structures.
830    For matched smb_saved_info structures we store the smb_saved_info
831    structure twice in the table using the frame number, and a combination
832    of the MID and the PID, as the key.
833    The frame number is guaranteed to be unique but if ever someone makes
834    some change that will renumber the frames in a capture we are in BIG trouble.
835    This is not likely though since that would break (among other things) all the
836    reassembly routines as well.
837
838    We also need the MID as there may be more than one SMB request or reply
839    in a single frame, and we also need the PID as there may be more than
840    one outstanding request with the same MID and different PIDs.
841 */
842 static gint
843 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
844 {
845         const smb_saved_info_key_t *key1 = k1;
846         const smb_saved_info_key_t *key2 = k2;
847         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
848 }
849 static guint
850 smb_saved_info_hash_matched(gconstpointer k)
851 {
852         const smb_saved_info_key_t *key = k;
853         return key->frame + key->pid_mid;
854 }
855
856 /*
857  * The information we need to save about an NT Transaction request in order
858  * to dissect the reply.
859  */
860 typedef struct {
861         int subcmd;
862 } smb_nt_transact_info_t;
863
864 static GMemChunk *smb_nt_transact_info_chunk = NULL;
865 static int smb_nt_transact_info_init_count = 200;
866
867 /*
868  * The information we need to save about a Transaction2 request in order
869  * to dissect the reply.
870  */
871 typedef struct {
872         int subcmd;
873         int info_level;
874         gboolean resume_keys;   /* if "return resume" keys set in T2 FIND_FIRST request */
875 } smb_transact2_info_t;
876
877 static GMemChunk *smb_transact2_info_chunk = NULL;
878 static int smb_transact2_info_init_count = 200;
879
880 /*
881  * The information we need to save about a Transaction request in order
882  * to dissect the reply; this includes information for use by the
883  * Remote API dissector.
884  */
885 static GMemChunk *smb_transact_info_chunk = NULL;
886 static int smb_transact_info_init_count = 200;
887
888 static GMemChunk *conv_tables_chunk = NULL;
889 static GSList *conv_tables = NULL;
890 static int conv_tables_count = 10;
891
892
893 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
894    End of request/response matching functions
895    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
896
897 static const value_string buffer_format_vals[] = {
898         {1,     "Data Block"},
899         {2,     "Dialect"},
900         {3,     "Pathname"},
901         {4,     "ASCII"},
902         {5,     "Variable Block"},
903         {0,     NULL}
904 };
905
906 /*
907  * UTIME - this is *almost* like a UNIX time stamp, except that it's
908  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
909  * January 1, 1970, 00:00:00 GMT.
910  *
911  * This means we have to do some extra work to convert it.  This code is
912  * based on the Samba code:
913  *
914  *      Unix SMB/Netbios implementation.
915  *      Version 1.9.
916  *      time handling functions
917  *      Copyright (C) Andrew Tridgell 1992-1998
918  */
919
920 /*
921  * Yield the difference between *A and *B, in seconds, ignoring leap
922  * seconds.
923  */
924 #define TM_YEAR_BASE 1900
925
926 static int
927 tm_diff(struct tm *a, struct tm *b)
928 {
929         int ay = a->tm_year + (TM_YEAR_BASE - 1);
930         int by = b->tm_year + (TM_YEAR_BASE - 1);
931         int intervening_leap_days =
932             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
933         int years = ay - by;
934         int days =
935             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
936         int hours = 24*days + (a->tm_hour - b->tm_hour);
937         int minutes = 60*hours + (a->tm_min - b->tm_min);
938         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
939
940         return seconds;
941 }
942
943 /*
944  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
945  * determined.
946  */
947 static int
948 TimeZone(time_t t)
949 {
950         struct tm *tm = gmtime(&t);
951         struct tm tm_utc;
952
953         if (tm == NULL)
954                 return 0;
955         tm_utc = *tm;
956         tm = localtime(&t);
957         if (tm == NULL)
958                 return 0;
959         return tm_diff(&tm_utc,tm);
960 }
961
962 /*
963  * Return the same value as TimeZone, but it should be more efficient.
964  *
965  * We keep a table of DST offsets to prevent calling localtime() on each 
966  * call of this function. This saves a LOT of time on many unixes.
967  *
968  * Updated by Paul Eggert <eggert@twinsun.com>
969  */
970 #ifndef CHAR_BIT
971 #define CHAR_BIT 8
972 #endif
973
974 #ifndef TIME_T_MIN
975 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
976                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
977 #endif
978 #ifndef TIME_T_MAX
979 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
980 #endif
981
982 static int
983 TimeZoneFaster(time_t t)
984 {
985         static struct dst_table {time_t start,end; int zone;} *tdt;
986         static struct dst_table *dst_table = NULL;
987         static int table_size = 0;
988         int i;
989         int zone = 0;
990
991         if (t == 0)
992                 t = time(NULL);
993
994         /* Tunis has a 8 day DST region, we need to be careful ... */
995 #define MAX_DST_WIDTH (365*24*60*60)
996 #define MAX_DST_SKIP (7*24*60*60)
997
998         for (i = 0; i < table_size; i++) {
999                 if (t >= dst_table[i].start && t <= dst_table[i].end)
1000                         break;
1001         }
1002
1003         if (i < table_size) {
1004                 zone = dst_table[i].zone;
1005         } else {
1006                 time_t low,high;
1007
1008                 zone = TimeZone(t);
1009                 if (dst_table == NULL)
1010                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1011                 else
1012                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1013                 if (tdt == NULL) {
1014                         if (dst_table)
1015                                 free(dst_table);
1016                         table_size = 0;
1017                 } else {
1018                         dst_table = tdt;
1019                         table_size++;
1020     
1021                         dst_table[i].zone = zone; 
1022                         dst_table[i].start = dst_table[i].end = t;
1023     
1024                         /* no entry will cover more than 6 months */
1025                         low = t - MAX_DST_WIDTH/2;
1026                         if (t < low)
1027                                 low = TIME_T_MIN;
1028       
1029                         high = t + MAX_DST_WIDTH/2;
1030                         if (high < t)
1031                                 high = TIME_T_MAX;
1032       
1033                         /*
1034                          * Widen the new entry using two bisection searches.
1035                          */
1036                         while (low+60*60 < dst_table[i].start) {
1037                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1038                                         t = dst_table[i].start - MAX_DST_SKIP;
1039                                 else
1040                                         t = low + (dst_table[i].start-low)/2;
1041                                 if (TimeZone(t) == zone)
1042                                         dst_table[i].start = t;
1043                                 else
1044                                         low = t;
1045                         }
1046
1047                         while (high-60*60 > dst_table[i].end) {
1048                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1049                                         t = dst_table[i].end + MAX_DST_SKIP;
1050                                 else
1051                                         t = high - (high-dst_table[i].end)/2;
1052                                 if (TimeZone(t) == zone)
1053                                         dst_table[i].end = t;
1054                                 else
1055                                         high = t;
1056                         }
1057                 }
1058         }
1059         return zone;
1060 }
1061
1062 /*
1063  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1064  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1065  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1066  * daylight savings transitions because some local times are ambiguous.
1067  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1068  */
1069 static int
1070 LocTimeDiff(time_t lt)
1071 {
1072         int d = TimeZoneFaster(lt);
1073         time_t t = lt + d;
1074
1075         /* if overflow occurred, ignore all the adjustments so far */
1076         if (((t < lt) ^ (d < 0)))
1077                 t = lt;
1078
1079         /*
1080          * Now t should be close enough to the true UTC to yield the
1081          * right answer.
1082          */
1083         return TimeZoneFaster(t);
1084 }
1085
1086 static int
1087 dissect_smb_UTIME(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_date)
1088 {
1089         guint32 timeval;
1090         nstime_t ts;
1091  
1092         timeval = tvb_get_letohl(tvb, offset);
1093         if (timeval == 0xffffffff) {
1094                 proto_tree_add_text(tree, tvb, offset, 4,
1095                     "%s: No time specified (0xffffffff)",
1096                     proto_registrar_get_name(hf_date));
1097                 offset += 4;
1098                 return offset;
1099         }
1100
1101         /*
1102          * We add the local time offset.
1103          */
1104         ts.secs = timeval + LocTimeDiff(timeval);
1105         ts.nsecs = 0;
1106
1107         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1108         offset += 4;
1109  
1110         return offset;
1111 }
1112
1113 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
1114
1115 /*
1116  * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits,
1117  * to an "nstime_t".
1118  * A FILETIME is a 64-bit integer, giving the time since Jan 1, 1601,
1119  * midnight "UTC", in 100ns units.
1120  * Return TRUE if the conversion succeeds, FALSE otherwise.
1121  *
1122  * According to the Samba code, it appears to be kludge-GMT (at least for
1123  * file listings). This means it's the GMT you get by taking a local time
1124  * and adding the server time zone offset.  This is NOT the same as GMT in
1125  * some cases.   However, we don't know the server time zone, so we don't
1126  * do that adjustment.
1127  *
1128  * This code is based on the Samba code:
1129  *
1130  *      Unix SMB/Netbios implementation.
1131  *      Version 1.9.
1132  *      time handling functions
1133  *      Copyright (C) Andrew Tridgell 1992-1998
1134  */
1135 static gboolean
1136 nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
1137 {
1138         double d;
1139         /* The next two lines are a fix needed for the 
1140             broken SCO compiler. JRA. */
1141         time_t l_time_min = TIME_T_MIN;
1142         time_t l_time_max = TIME_T_MAX;
1143
1144         if (filetime_high == 0)
1145                 return FALSE;
1146
1147         /*
1148          * Get the time as a double, in seconds and fractional seconds.
1149          */
1150         d = ((double)filetime_high)*4.0*(double)(1<<30);
1151         d += filetime_low;
1152         d *= 1.0e-7;
1153  
1154         /* Now adjust by 369 years, to make the seconds since 1970. */
1155         d -= TIME_FIXUP_CONSTANT;
1156
1157         if (!(l_time_min <= d && d <= l_time_max))
1158                 return FALSE;
1159
1160         /*
1161          * Get the time as seconds and nanoseconds.
1162          */
1163         tv->secs = d;
1164         tv->nsecs = (d - tv->secs)*1000000000;
1165
1166         return TRUE;
1167 }
1168
1169 int
1170 dissect_smb_64bit_time(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_date)
1171 {
1172         guint32 filetime_high, filetime_low;
1173         nstime_t ts;
1174
1175         /* XXX there seems also to be another special time value which is fairly common :
1176            0x40000000 00000000  
1177            the meaning of this one is yet unknown 
1178         */
1179         if (tree) {
1180                 filetime_low = tvb_get_letohl(tvb, offset);
1181                 filetime_high = tvb_get_letohl(tvb, offset + 4);
1182                 if (filetime_low == 0 && filetime_high == 0) {
1183                         proto_tree_add_text(tree, tvb, offset, 8,
1184                             "%s: No time specified (0)",
1185                             proto_registrar_get_name(hf_date));
1186                 } else if(filetime_low==0 && filetime_high==0x80000000){
1187                         proto_tree_add_text(tree, tvb, offset, 8,
1188                             "%s: Infinity (relative time)",
1189                             proto_registrar_get_name(hf_date));
1190                 } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
1191                         proto_tree_add_text(tree, tvb, offset, 8,
1192                             "%s: Infinity (absolute time)",
1193                             proto_registrar_get_name(hf_date));
1194                 } else {                        
1195                         if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
1196                                 proto_tree_add_time(tree, hf_date, tvb,
1197                                     offset, 8, &ts);
1198                         } else {
1199                                 proto_tree_add_text(tree, tvb, offset, 8,
1200                                     "%s: Time can't be converted",
1201                                     proto_registrar_get_name(hf_date));
1202                         }
1203                 }
1204         }
1205
1206         offset += 8;
1207         return offset;
1208 }
1209
1210 static int
1211 dissect_smb_datetime(tvbuff_t *tvb, packet_info *pinfo,
1212     proto_tree *parent_tree, int offset, int hf_date, int hf_dos_date,
1213     int hf_dos_time, gboolean time_first)
1214 {
1215         guint16 dos_time, dos_date;
1216         proto_item *item = NULL;
1217         proto_tree *tree = NULL;
1218         struct tm tm;
1219         time_t t;
1220         static const int mday_noleap[12] = {
1221                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1222         };
1223         static const int mday_leap[12] = {
1224                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1225         };
1226 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1227         nstime_t tv;
1228
1229         if (time_first) {
1230                 dos_time = tvb_get_letohs(tvb, offset);
1231                 dos_date = tvb_get_letohs(tvb, offset+2);
1232         } else {
1233                 dos_date = tvb_get_letohs(tvb, offset);
1234                 dos_time = tvb_get_letohs(tvb, offset+2);
1235         }
1236
1237         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1238             (dos_date == 0 && dos_time == 0)) {
1239                 /*
1240                  * No date/time specified.
1241                  */
1242                 if(parent_tree){
1243                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1244                             "%s: No time specified (0x%08x)",
1245                             proto_registrar_get_name(hf_date),
1246                             (dos_date << 16) | dos_time);
1247                 }
1248                 offset += 4;
1249                 return offset;
1250         }
1251
1252         tm.tm_sec = (dos_time&0x1f)*2;
1253         tm.tm_min = (dos_time>>5)&0x3f;
1254         tm.tm_hour = (dos_time>>11)&0x1f;
1255         tm.tm_mday = dos_date&0x1f;
1256         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1257         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1258         tm.tm_isdst = -1;
1259
1260         /*
1261          * Do some sanity checks before calling "mktime()";
1262          * "mktime()" doesn't do them, it "normalizes" out-of-range
1263          * values.
1264          */
1265         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1266            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1267            (ISLEAP(tm.tm_year + 1900) ?
1268              tm.tm_mday > mday_leap[tm.tm_mon] :
1269              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1270              (t = mktime(&tm)) == -1) {
1271                 /*
1272                  * Invalid date/time.
1273                  */
1274                 if (parent_tree) {
1275                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1276                             "%s: Invalid time",
1277                             proto_registrar_get_name(hf_date));
1278                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1279                         if (time_first) {
1280                                 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);
1281                                 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);
1282                         } else {
1283                                 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);
1284                                 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);
1285                         }
1286                 }
1287                 offset += 4;
1288                 return offset;
1289         }
1290
1291         tv.secs = t;
1292         tv.nsecs = 0;
1293
1294         if(parent_tree){
1295                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1296                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1297                 if (time_first) {
1298                         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);
1299                         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);
1300                 } else {
1301                         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);
1302                         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);
1303                 }
1304         }
1305
1306         offset += 4;
1307
1308         return offset;
1309 }
1310
1311
1312 static const value_string da_access_vals[] = {
1313         { 0,            "Open for reading"},
1314         { 1,            "Open for writing"},
1315         { 2,            "Open for reading and writing"},
1316         { 3,            "Open for execute"},
1317         {0, NULL}
1318 };
1319 static const value_string da_sharing_vals[] = {
1320         { 0,            "Compatibility mode"},
1321         { 1,            "Deny read/write/execute (exclusive)"},
1322         { 2,            "Deny write"},
1323         { 3,            "Deny read/execute"},
1324         { 4,            "Deny none"},
1325         {0, NULL}
1326 };
1327 static const value_string da_locality_vals[] = {
1328         { 0,            "Locality of reference unknown"},
1329         { 1,            "Mainly sequential access"},
1330         { 2,            "Mainly random access"},
1331         { 3,            "Random access with some locality"},
1332         {0, NULL}
1333 };
1334 static const true_false_string tfs_da_caching = {
1335         "Do not cache this file",
1336         "Caching permitted on this file"
1337 };
1338 static const true_false_string tfs_da_writetru = {
1339         "Write through enabled",
1340         "Write through disabled"
1341 };
1342 static int
1343 dissect_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, char *type)
1344 {
1345         guint16 mask;
1346         proto_item *item = NULL;
1347         proto_tree *tree = NULL;
1348
1349         mask = tvb_get_letohs(tvb, offset);
1350
1351         if(parent_tree){
1352                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1353                         "%s Access: 0x%04x", type, mask);
1354                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1355         }
1356
1357         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1358                 tvb, offset, 2, mask);
1359         proto_tree_add_boolean(tree, hf_smb_access_caching,
1360                 tvb, offset, 2, mask);
1361         proto_tree_add_uint(tree, hf_smb_access_locality,
1362                 tvb, offset, 2, mask);
1363         proto_tree_add_uint(tree, hf_smb_access_sharing,
1364                 tvb, offset, 2, mask);
1365         proto_tree_add_uint(tree, hf_smb_access_mode,
1366                 tvb, offset, 2, mask);
1367
1368         offset += 2;
1369
1370         return offset;
1371 }
1372
1373 #define FILE_ATTRIBUTE_READ_ONLY                0x00000001
1374 #define FILE_ATTRIBUTE_HIDDEN                   0x00000002
1375 #define FILE_ATTRIBUTE_SYSTEM                   0x00000004
1376 #define FILE_ATTRIBUTE_VOLUME                   0x00000008
1377 #define FILE_ATTRIBUTE_DIRECTORY                0x00000010
1378 #define FILE_ATTRIBUTE_ARCHIVE                  0x00000020
1379 #define FILE_ATTRIBUTE_DEVICE                   0x00000040
1380 #define FILE_ATTRIBUTE_NORMAL                   0x00000080
1381 #define FILE_ATTRIBUTE_TEMPORARY                0x00000100
1382 #define FILE_ATTRIBUTE_SPARSE                   0x00000200
1383 #define FILE_ATTRIBUTE_REPARSE                  0x00000400
1384 #define FILE_ATTRIBUTE_COMPRESSED               0x00000800
1385 #define FILE_ATTRIBUTE_OFFLINE                  0x00001000
1386 #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED      0x00002000
1387 #define FILE_ATTRIBUTE_ENCRYPTED                0x00004000
1388
1389 /*
1390  * These are flags to be used in NT Create operations.
1391  */
1392 #define FILE_ATTRIBUTE_WRITE_THROUGH            0x80000000
1393 #define FILE_ATTRIBUTE_NO_BUFFERING             0x20000000
1394 #define FILE_ATTRIBUTE_RANDOM_ACCESS            0x10000000
1395 #define FILE_ATTRIBUTE_SEQUENTIAL_SCAN          0x08000000
1396 #define FILE_ATTRIBUTE_DELETE_ON_CLOSE          0x04000000
1397 #define FILE_ATTRIBUTE_BACKUP_SEMANTICS         0x02000000
1398 #define FILE_ATTRIBUTE_POSIX_SEMANTICS          0x01000000
1399
1400 static const true_false_string tfs_file_attribute_write_through = {
1401         "This object requires WRITE THROUGH",
1402         "This object does NOT require write through",
1403 };
1404 static const true_false_string tfs_file_attribute_no_buffering = {
1405         "This object requires NO BUFFERING",
1406         "This object can be buffered",
1407 };
1408 static const true_false_string tfs_file_attribute_random_access = {
1409         "This object will be RANDOM ACCESSed",
1410         "Random access is NOT requested",
1411 };
1412 static const true_false_string tfs_file_attribute_sequential_scan = {
1413         "This object is optimized for SEQUENTIAL SCAN",
1414         "This object is NOT optimized for sequential scan",
1415 };
1416 static const true_false_string tfs_file_attribute_delete_on_close = {
1417         "This object will be DELETED ON CLOSE",
1418         "This object will not be deleted on close",
1419 };
1420 static const true_false_string tfs_file_attribute_backup_semantics = {
1421         "This object supports BACKUP SEMANTICS",
1422         "This object does NOT support backup semantics",
1423 };
1424 static const true_false_string tfs_file_attribute_posix_semantics = {
1425         "This object supports POSIX SEMANTICS",
1426         "This object does NOT support POSIX semantics",
1427 };
1428 static const true_false_string tfs_file_attribute_read_only = {
1429         "This file is READ ONLY",
1430         "This file is NOT read only",
1431 };
1432 static const true_false_string tfs_file_attribute_hidden = {
1433         "This is a HIDDEN file",
1434         "This is NOT a hidden file"
1435 };
1436 static const true_false_string tfs_file_attribute_system = {
1437         "This is a SYSTEM file",
1438         "This is NOT a system file"
1439 };
1440 static const true_false_string tfs_file_attribute_volume = {
1441         "This is a VOLUME ID",
1442         "This is NOT a volume ID"
1443 };
1444 static const true_false_string tfs_file_attribute_directory = {
1445         "This is a DIRECTORY",
1446         "This is NOT a directory"
1447 };
1448 static const true_false_string tfs_file_attribute_archive = {
1449         "This is an ARCHIVE file",
1450         "This is NOT an archive file"
1451 };
1452 static const true_false_string tfs_file_attribute_device = {
1453         "This is a DEVICE",
1454         "This is NOT a device"
1455 };
1456 static const true_false_string tfs_file_attribute_normal = {
1457         "This file is an ordinary file",
1458         "This file has some attribute set"
1459 };
1460 static const true_false_string tfs_file_attribute_temporary = {
1461         "This is a TEMPORARY file",
1462         "This is NOT a temporary file"
1463 };
1464 static const true_false_string tfs_file_attribute_sparse = {
1465         "This is a SPARSE file",
1466         "This is NOT a sparse file"
1467 };
1468 static const true_false_string tfs_file_attribute_reparse = {
1469         "This file has an associated REPARSE POINT",
1470         "This file does NOT have an associated reparse point"
1471 };
1472 static const true_false_string tfs_file_attribute_compressed = {
1473         "This is a COMPRESSED file",
1474         "This is NOT a compressed file"
1475 };
1476 static const true_false_string tfs_file_attribute_offline = {
1477         "This file is OFFLINE",
1478         "This file is NOT offline"
1479 };
1480 static const true_false_string tfs_file_attribute_not_content_indexed = {
1481         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1482         "This file MAY be indexed by the content indexing service"
1483 };
1484 static const true_false_string tfs_file_attribute_encrypted = {
1485         "This is an ENCRYPTED file",
1486         "This is NOT an encrypted file"
1487 };
1488
1489 static int
1490 dissect_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1491 {
1492         guint16 mask;
1493         proto_item *item = NULL;
1494         proto_tree *tree = NULL;
1495
1496         mask = tvb_get_letohs(tvb, offset);
1497
1498         if(parent_tree){
1499                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1500                         "File Attributes: 0x%04x", mask);
1501                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1502         }
1503         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1504                 tvb, offset, 2, mask);
1505         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1506                 tvb, offset, 2, mask);
1507         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1508                 tvb, offset, 2, mask);
1509         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1510                 tvb, offset, 2, mask);
1511         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1512                 tvb, offset, 2, mask);
1513         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1514                 tvb, offset, 2, mask);
1515
1516         offset += 2;
1517
1518         return offset;
1519 }
1520
1521 /* 3.11 */
1522 static int
1523 dissect_file_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1524 {
1525         guint32 mask;
1526         proto_item *item = NULL;
1527         proto_tree *tree = NULL;
1528
1529         mask = tvb_get_letohl(tvb, offset);
1530
1531         if(parent_tree){
1532                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1533                         "File Attributes: 0x%08x", mask);
1534                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1535         }
1536
1537         /*
1538          * XXX - Network Monitor disagrees on some of the
1539          * bits, e.g. the bits above temporary are "atomic write"
1540          * and "transaction write", and it says nothing about the
1541          * bits above that.
1542          *
1543          * Does the Win32 API documentation, or the NT Native API book,
1544          * suggest anything?
1545          */
1546         proto_tree_add_boolean(tree, hf_smb_file_eattr_write_through,
1547                 tvb, offset, 4, mask);
1548         proto_tree_add_boolean(tree, hf_smb_file_eattr_no_buffering,
1549                 tvb, offset, 4, mask);
1550         proto_tree_add_boolean(tree, hf_smb_file_eattr_random_access,
1551                 tvb, offset, 4, mask);
1552         proto_tree_add_boolean(tree, hf_smb_file_eattr_sequential_scan,
1553                 tvb, offset, 4, mask);
1554         proto_tree_add_boolean(tree, hf_smb_file_eattr_delete_on_close,
1555                 tvb, offset, 4, mask);
1556         proto_tree_add_boolean(tree, hf_smb_file_eattr_backup_semantics,
1557                 tvb, offset, 4, mask);
1558         proto_tree_add_boolean(tree, hf_smb_file_eattr_posix_semantics,
1559                 tvb, offset, 4, mask);
1560         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1561                 tvb, offset, 4, mask);
1562         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1563                 tvb, offset, 4, mask);
1564         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1565                 tvb, offset, 4, mask);
1566         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1567                 tvb, offset, 4, mask);
1568         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1569                 tvb, offset, 4, mask);
1570         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1571                 tvb, offset, 4, mask);
1572         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1573                 tvb, offset, 4, mask);
1574         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1575                 tvb, offset, 4, mask);
1576         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1577                 tvb, offset, 4, mask);
1578         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1579                 tvb, offset, 4, mask);
1580         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1581                 tvb, offset, 4, mask);
1582         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1583                 tvb, offset, 4, mask);
1584         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1585                 tvb, offset, 4, mask);
1586         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1587                 tvb, offset, 4, mask);
1588         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1589                 tvb, offset, 4, mask);
1590
1591         offset += 4;
1592
1593         return offset;
1594 }
1595
1596 static int
1597 dissect_dir_info_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1598 {
1599         guint8 mask;
1600         proto_item *item = NULL;
1601         proto_tree *tree = NULL;
1602
1603         mask = tvb_get_guint8(tvb, offset);
1604
1605         if(parent_tree){
1606                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1607                         "File Attributes: 0x%02x", mask);
1608                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1609         }
1610         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1611                 tvb, offset, 1, mask);
1612         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1613                 tvb, offset, 1, mask);
1614         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1615                 tvb, offset, 1, mask);
1616         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1617                 tvb, offset, 1, mask);
1618         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1619                 tvb, offset, 1, mask);
1620         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1621                 tvb, offset, 1, mask);
1622
1623         offset += 1;
1624
1625         return offset;
1626 }
1627
1628 static const true_false_string tfs_search_attribute_read_only = {
1629         "Include READ ONLY files in search results",
1630         "Do NOT include read only files in search results",
1631 };
1632 static const true_false_string tfs_search_attribute_hidden = {
1633         "Include HIDDEN files in search results",
1634         "Do NOT include hidden files in search results"
1635 };
1636 static const true_false_string tfs_search_attribute_system = {
1637         "Include SYSTEM files in search results",
1638         "Do NOT include system files in search results"
1639 };
1640 static const true_false_string tfs_search_attribute_volume = {
1641         "Include VOLUME IDs in search results",
1642         "Do NOT include volume IDs in search results"
1643 };
1644 static const true_false_string tfs_search_attribute_directory = {
1645         "Include DIRECTORIES in search results",
1646         "Do NOT include directories in search results"
1647 };
1648 static const true_false_string tfs_search_attribute_archive = {
1649         "Include ARCHIVE files in search results",
1650         "Do NOT include archive files in search results"
1651 };
1652
1653 static int
1654 dissect_search_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1655 {
1656         guint16 mask;
1657         proto_item *item = NULL;
1658         proto_tree *tree = NULL;
1659
1660         mask = tvb_get_letohs(tvb, offset);
1661
1662         if(parent_tree){
1663                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1664                         "Search Attributes: 0x%04x", mask);
1665                 tree = proto_item_add_subtree(item, ett_smb_search);
1666         }
1667
1668         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1669                 tvb, offset, 2, mask);
1670         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1671                 tvb, offset, 2, mask);
1672         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1673                 tvb, offset, 2, mask);  
1674         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1675                 tvb, offset, 2, mask);
1676         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1677                 tvb, offset, 2, mask);
1678         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1679                 tvb, offset, 2, mask);
1680
1681         offset += 2;
1682         return offset;
1683 }
1684
1685 #if 0
1686 /*
1687  * XXX - this isn't used.
1688  * Is this used for anything?  NT Create AndX doesn't use it.
1689  * Is there some 16-bit attribute field with more bits than Read Only,
1690  * Hidden, System, Volume ID, Directory, and Archive?
1691  */
1692 static int
1693 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1694 {
1695         guint32 mask;
1696         proto_item *item = NULL;
1697         proto_tree *tree = NULL;
1698
1699         mask = tvb_get_letohl(tvb, offset);
1700
1701         if(parent_tree){
1702                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1703                         "File Attributes: 0x%08x", mask);
1704                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1705         }
1706         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1707                 tvb, offset, 2, mask);
1708         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1709                 tvb, offset, 2, mask);
1710         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1711                 tvb, offset, 2, mask);
1712         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1713                 tvb, offset, 2, mask);
1714         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1715                 tvb, offset, 2, mask);
1716         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1717                 tvb, offset, 2, mask);
1718         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1719                 tvb, offset, 2, mask);
1720         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1721                 tvb, offset, 2, mask);
1722         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1723                 tvb, offset, 2, mask);
1724         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1725                 tvb, offset, 2, mask);
1726         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1727                 tvb, offset, 2, mask);
1728         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1729                 tvb, offset, 2, mask);
1730         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1731                 tvb, offset, 2, mask);
1732         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1733                 tvb, offset, 2, mask);
1734         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1735                 tvb, offset, 2, mask);
1736
1737         offset += 2;
1738
1739         return offset;
1740 }
1741 #endif
1742
1743
1744 #define SERVER_CAP_RAW_MODE            0x00000001
1745 #define SERVER_CAP_MPX_MODE            0x00000002
1746 #define SERVER_CAP_UNICODE             0x00000004
1747 #define SERVER_CAP_LARGE_FILES         0x00000008
1748 #define SERVER_CAP_NT_SMBS             0x00000010
1749 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1750 #define SERVER_CAP_STATUS32            0x00000040
1751 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1752 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1753 #define SERVER_CAP_NT_FIND             0x00000200
1754 #define SERVER_CAP_DFS                 0x00001000
1755 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1756 #define SERVER_CAP_LARGE_READX         0x00004000
1757 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1758 #define SERVER_CAP_UNIX                0x00800000
1759 #define SERVER_CAP_RESERVED            0x02000000
1760 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1761 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1762 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1763 static const true_false_string tfs_server_cap_raw_mode = {
1764         "Read Raw and Write Raw are supported",
1765         "Read Raw and Write Raw are not supported"
1766 };
1767 static const true_false_string tfs_server_cap_mpx_mode = {
1768         "Read Mpx and Write Mpx are supported",
1769         "Read Mpx and Write Mpx are not supported"
1770 };
1771 static const true_false_string tfs_server_cap_unicode = {
1772         "Unicode strings are supported",
1773         "Unicode strings are not supported"
1774 };
1775 static const true_false_string tfs_server_cap_large_files = {
1776         "Large files are supported",
1777         "Large files are not supported",
1778 };
1779 static const true_false_string tfs_server_cap_nt_smbs = {
1780         "NT SMBs are supported",
1781         "NT SMBs are not supported"
1782 };
1783 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1784         "RPC remote APIs are supported",
1785         "RPC remote APIs are not supported"
1786 };
1787 static const true_false_string tfs_server_cap_nt_status = {
1788         "NT status codes are supported",
1789         "NT status codes are not supported"
1790 };
1791 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1792         "Level 2 oplocks are supported",
1793         "Level 2 oplocks are not supported"
1794 };
1795 static const true_false_string tfs_server_cap_lock_and_read = {
1796         "Lock and Read is supported",
1797         "Lock and Read is not supported"
1798 };
1799 static const true_false_string tfs_server_cap_nt_find = {
1800         "NT Find is supported",
1801         "NT Find is not supported"
1802 };
1803 static const true_false_string tfs_server_cap_dfs = {
1804         "Dfs is supported",
1805         "Dfs is not supported"
1806 };
1807 static const true_false_string tfs_server_cap_infolevel_passthru = {
1808         "NT information level request passthrough is supported",
1809         "NT information level request passthrough is not supported"
1810 };
1811 static const true_false_string tfs_server_cap_large_readx = {
1812         "Large Read andX is supported",
1813         "Large Read andX is not supported"
1814 };
1815 static const true_false_string tfs_server_cap_large_writex = {
1816         "Large Write andX is supported",
1817         "Large Write andX is not supported"
1818 };
1819 static const true_false_string tfs_server_cap_unix = {
1820         "UNIX extensions are supported",
1821         "UNIX extensions are not supported"
1822 };
1823 static const true_false_string tfs_server_cap_reserved = {
1824         "Reserved",
1825         "Reserved"
1826 };
1827 static const true_false_string tfs_server_cap_bulk_transfer = {
1828         "Bulk Read and Bulk Write are supported",
1829         "Bulk Read and Bulk Write are not supported"
1830 };
1831 static const true_false_string tfs_server_cap_compressed_data = {
1832         "Compressed data transfer is supported",
1833         "Compressed data transfer is not supported"
1834 };
1835 static const true_false_string tfs_server_cap_extended_security = {
1836         "Extended security exchanges are supported",
1837         "Extended security exchanges are not supported"
1838 };
1839 static int
1840 dissect_negprot_capabilities(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1841 {
1842         guint32 mask;
1843         proto_item *item = NULL;
1844         proto_tree *tree = NULL;
1845
1846         mask = tvb_get_letohl(tvb, offset);
1847
1848         if(parent_tree){
1849                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1850                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1851         }
1852
1853         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1854                 tvb, offset, 4, mask);
1855         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1856                 tvb, offset, 4, mask);
1857         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1858                 tvb, offset, 4, mask);
1859         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1860                 tvb, offset, 4, mask);
1861         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1862                 tvb, offset, 4, mask);
1863         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1864                 tvb, offset, 4, mask);
1865         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1866                 tvb, offset, 4, mask);
1867         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1868                 tvb, offset, 4, mask);
1869         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1870                 tvb, offset, 4, mask);
1871         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1872                 tvb, offset, 4, mask);
1873         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1874                 tvb, offset, 4, mask);
1875         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1876                 tvb, offset, 4, mask);
1877         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1878                 tvb, offset, 4, mask);
1879         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1880                 tvb, offset, 4, mask);
1881         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1882                 tvb, offset, 4, mask);
1883         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1884                 tvb, offset, 4, mask);
1885         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1886                 tvb, offset, 4, mask);
1887         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1888                 tvb, offset, 4, mask);
1889         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1890                 tvb, offset, 4, mask);
1891
1892         return mask;
1893 }
1894
1895 #define RAWMODE_READ   0x01
1896 #define RAWMODE_WRITE  0x02
1897 static const true_false_string tfs_rm_read = {
1898         "Read Raw is supported",
1899         "Read Raw is not supported"
1900 };
1901 static const true_false_string tfs_rm_write = {
1902         "Write Raw is supported",
1903         "Write Raw is not supported"
1904 };
1905
1906 static int
1907 dissect_negprot_rawmode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1908 {
1909         guint16 mask;
1910         proto_item *item = NULL;
1911         proto_tree *tree = NULL;
1912
1913         mask = tvb_get_letohs(tvb, offset);
1914
1915         if(parent_tree){
1916                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1917                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1918         }
1919
1920         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
1921         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
1922
1923         offset += 2;
1924
1925         return offset;
1926 }
1927
1928 #define SECURITY_MODE_MODE             0x01
1929 #define SECURITY_MODE_PASSWORD         0x02
1930 #define SECURITY_MODE_SIGNATURES       0x04
1931 #define SECURITY_MODE_SIG_REQUIRED     0x08
1932 static const true_false_string tfs_sm_mode = {
1933         "USER security mode",
1934         "SHARE security mode"
1935 };
1936 static const true_false_string tfs_sm_password = {
1937         "ENCRYPTED password. Use challenge/response",
1938         "PLAINTEXT password"
1939 };
1940 static const true_false_string tfs_sm_signatures = {
1941         "Security signatures ENABLED",
1942         "Security signatures NOT enabled"
1943 };
1944 static const true_false_string tfs_sm_sig_required = {
1945         "Security signatures REQUIRED",
1946         "Security signatures NOT required"
1947 };
1948
1949 static int
1950 dissect_negprot_security_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int wc)
1951 {
1952         guint16 mask = 0;
1953         proto_item *item = NULL;
1954         proto_tree *tree = NULL;
1955
1956         switch(wc){
1957         case 13:
1958                 mask = tvb_get_letohs(tvb, offset);
1959                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1960                                 "Security Mode: 0x%04x", mask);
1961                 tree = proto_item_add_subtree(item, ett_smb_mode);
1962                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
1963                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
1964                 offset += 2;
1965                 break;
1966
1967         case 17:
1968                 mask = tvb_get_guint8(tvb, offset);
1969                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1970                                 "Security Mode: 0x%02x", mask);
1971                 tree = proto_item_add_subtree(item, ett_smb_mode);
1972                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
1973                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
1974                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
1975                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
1976                 offset += 1;
1977                 break;
1978         }
1979
1980         return offset;
1981 }
1982
1983 static int
1984 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
1985 {
1986         proto_item *it = NULL;
1987         proto_tree *tr = NULL;
1988         guint16 bc;
1989         guint8 wc;
1990
1991         WORD_COUNT;
1992
1993         BYTE_COUNT;
1994
1995         if(tree){
1996                 it = proto_tree_add_text(tree, tvb, offset, bc,
1997                                 "Requested Dialects");
1998                 tr = proto_item_add_subtree(it, ett_smb_dialects);
1999         }
2000
2001         while(bc){
2002                 int len;
2003                 const guint8 *str;
2004                 proto_item *dit = NULL;
2005                 proto_tree *dtr = NULL;
2006
2007                 /* XXX - what if this runs past bc? */
2008                 len = tvb_strsize(tvb, offset+1);
2009                 str = tvb_get_ptr(tvb, offset+1, len);
2010
2011                 if(tr){
2012                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2013                                         "Dialect: %s", str);
2014                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2015                 }
2016
2017                 /* Buffer Format */
2018                 CHECK_BYTE_COUNT(1);
2019                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2020                         TRUE);
2021                 COUNT_BYTES(1);
2022
2023                 /*Dialect Name */
2024                 CHECK_BYTE_COUNT(len);
2025                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2026                         len, str);
2027                 COUNT_BYTES(len);
2028         }
2029
2030         END_OF_SMB
2031
2032         return offset;
2033 }
2034
2035 static int
2036 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2037 {
2038         guint8 wc;
2039         guint16 dialect;
2040         const char *dn;
2041         int dn_len;
2042         guint16 bc;
2043         guint16 ekl=0;
2044         guint32 caps=0;
2045         gint16 tz;
2046
2047         WORD_COUNT;
2048
2049         /* Dialect Index */
2050         dialect = tvb_get_letohs(tvb, offset);
2051         switch(wc){
2052         case 1:
2053                 if(dialect==0xffff){
2054                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2055                                 tvb, offset, 2, dialect,
2056                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2057                 } else {
2058                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2059                                 tvb, offset, 2, dialect);
2060                 }
2061                 break;
2062         case 13:
2063                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2064                         tvb, offset, 2, dialect,
2065                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2066                 break;
2067         case 17:
2068                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2069                         tvb, offset, 2, dialect,
2070                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2071                 break;
2072         default:
2073                 proto_tree_add_text(tree, tvb, offset, wc*2,
2074                         "Words for unknown response format");
2075                 offset += wc*2;
2076                 goto bytecount;
2077         }
2078         offset += 2;
2079
2080         switch(wc){
2081         case 13:
2082                 /* Security Mode */
2083                 offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset,
2084                                 wc);
2085
2086                 /* Maximum Transmit Buffer Size */
2087                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2088                         tvb, offset, 2, TRUE);
2089                 offset += 2;
2090
2091                 /* Maximum Multiplex Count */
2092                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2093                         tvb, offset, 2, TRUE);
2094                 offset += 2;
2095
2096                 /* Maximum Vcs Number */
2097                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2098                         tvb, offset, 2, TRUE);
2099                 offset += 2;
2100
2101                 /* raw mode */
2102                 offset = dissect_negprot_rawmode(tvb, pinfo, tree, offset);
2103
2104                 /* session key */
2105                 proto_tree_add_item(tree, hf_smb_session_key,
2106                         tvb, offset, 4, TRUE);
2107                 offset += 4;
2108
2109                 /* current time and date at server */
2110                 offset = dissect_smb_datetime(tvb, pinfo, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2111                     TRUE);
2112
2113                 /* time zone */
2114                 tz = tvb_get_letohs(tvb, offset);
2115                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2116                 offset += 2;
2117
2118                 /* encryption key length */
2119                 ekl = tvb_get_letohs(tvb, offset);
2120                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2121                 offset += 2;
2122
2123                 /* 2 reserved bytes */
2124                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2125                 offset += 2;
2126
2127                 break;
2128
2129         case 17:
2130                 /* Security Mode */
2131                 offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset, wc);
2132
2133                 /* Maximum Multiplex Count */
2134                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2135                         tvb, offset, 2, TRUE);
2136                 offset += 2;
2137
2138                 /* Maximum Vcs Number */
2139                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2140                         tvb, offset, 2, TRUE);
2141                 offset += 2;
2142
2143                 /* Maximum Transmit Buffer Size */
2144                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2145                         tvb, offset, 4, TRUE);
2146                 offset += 4;
2147
2148                 /* maximum raw buffer size */
2149                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2150                         tvb, offset, 4, TRUE);
2151                 offset += 4;
2152
2153                 /* session key */
2154                 proto_tree_add_item(tree, hf_smb_session_key,
2155                         tvb, offset, 4, TRUE);
2156                 offset += 4;
2157
2158                 /* server capabilities */
2159                 caps = dissect_negprot_capabilities(tvb, pinfo, tree, offset);
2160                 offset += 4;
2161
2162                 /* system time */
2163                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
2164                                 hf_smb_system_time);
2165
2166                 /* time zone */
2167                 tz = tvb_get_letohs(tvb, offset);
2168                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2169                         tvb, offset, 2, tz,
2170                         "Server Time Zone: %d min from UTC", tz);
2171                 offset += 2;
2172
2173                 /* encryption key length */
2174                 ekl = tvb_get_guint8(tvb, offset);
2175                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2176                         tvb, offset, 1, ekl);
2177                 offset += 1;
2178
2179                 break;
2180         }
2181
2182         BYTE_COUNT;
2183
2184         switch(wc){
2185         case 13:
2186                 /* challenge/response encryption key */
2187                 if(ekl){
2188                         CHECK_BYTE_COUNT(ekl);
2189                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2190                         COUNT_BYTES(ekl);
2191                 }
2192
2193                 /*
2194                  * Primary domain.
2195                  *
2196                  * XXX - not present if negotiated dialect isn't
2197                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2198                  * have to see the request, or assume what dialect strings
2199                  * were sent, to determine that.
2200                  */
2201                 dn = get_unicode_or_ascii_string(tvb, &offset,
2202                         pinfo, &dn_len, FALSE, FALSE, &bc);
2203                 if (dn == NULL)
2204                         goto endofcommand;
2205                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2206                         offset, dn_len,dn);
2207                 COUNT_BYTES(dn_len);
2208                 break;
2209
2210         case 17:
2211                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2212                         smb_info_t *si;
2213
2214                         /* challenge/response encryption key */
2215                         /* XXX - is this aligned on an even boundary? */
2216                         if(ekl){
2217                                 CHECK_BYTE_COUNT(ekl);
2218                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2219                                         tvb, offset, ekl, TRUE);
2220                                 COUNT_BYTES(ekl);
2221                         }
2222
2223                         /* domain */
2224                         /* this string is special, unicode is flagged in caps */
2225                         /* This string is NOT padded to be 16bit aligned. (seen in actual capture) */
2226                         si = pinfo->private_data;
2227                         si->unicode = (caps&SERVER_CAP_UNICODE);
2228                         dn = get_unicode_or_ascii_string(tvb,
2229                                 &offset, pinfo, &dn_len, TRUE, FALSE,
2230                                 &bc);
2231                         if (dn == NULL)
2232                                 goto endofcommand;
2233                         proto_tree_add_string(tree, hf_smb_primary_domain,
2234                                 tvb, offset, dn_len, dn);
2235                         COUNT_BYTES(dn_len);
2236                 } else {
2237                         /* guid */
2238                         /* XXX - show it in the standard Microsoft format
2239                            for GUIDs? */
2240                         CHECK_BYTE_COUNT(16);
2241                         proto_tree_add_item(tree, hf_smb_server_guid,
2242                                 tvb, offset, 16, TRUE);
2243                         COUNT_BYTES(16);
2244
2245                         /* security blob */
2246                         /* XXX - is this ASN.1-encoded?  Is it a Kerberos
2247                            data structure, at least in NT 5.0-and-later
2248                            server replies? */
2249                         if(bc){
2250                                 proto_tree_add_item(tree, hf_smb_security_blob,
2251                                         tvb, offset, bc, TRUE);
2252                                 COUNT_BYTES(bc);
2253                         }
2254                 }
2255                 break;
2256         }
2257
2258         END_OF_SMB
2259
2260         return offset;
2261 }
2262
2263
2264 static int
2265 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2266 {
2267         int dn_len;
2268         const char *dn;
2269         guint8 wc;
2270         guint16 bc;
2271
2272         WORD_COUNT;
2273  
2274         BYTE_COUNT;
2275
2276         /* buffer format */
2277         CHECK_BYTE_COUNT(1);
2278         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2279         COUNT_BYTES(1);
2280
2281         /* dir name */
2282         dn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &dn_len,
2283                 FALSE, FALSE, &bc);
2284         if (dn == NULL)
2285                 goto endofcommand;
2286         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2287                 dn);
2288         COUNT_BYTES(dn_len);
2289
2290         if (check_col(pinfo->cinfo, COL_INFO)) {
2291                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s", dn);
2292         }
2293
2294         END_OF_SMB
2295
2296         return offset;
2297 }
2298
2299 static int
2300 dissect_empty(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2301 {
2302         guint8 wc;
2303         guint16 bc;
2304  
2305         WORD_COUNT;
2306  
2307         BYTE_COUNT;
2308
2309         END_OF_SMB
2310
2311         return offset;
2312 }
2313
2314 static int
2315 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2316 {
2317         guint16 ec, bc;
2318         guint8 wc;
2319
2320         WORD_COUNT;
2321
2322         /* echo count */
2323         ec = tvb_get_letohs(tvb, offset);
2324         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2325         offset += 2;
2326
2327         BYTE_COUNT;
2328
2329         if (bc != 0) {
2330                 /* echo data */
2331                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2332                 COUNT_BYTES(bc);
2333         }
2334
2335         END_OF_SMB
2336
2337         return offset;
2338 }
2339
2340 static int
2341 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2342 {
2343         guint16 bc;
2344         guint8 wc;
2345
2346         WORD_COUNT;
2347
2348         /* echo sequence number */
2349         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2350         offset += 2;
2351
2352         BYTE_COUNT;
2353
2354         if (bc != 0) {
2355                 /* echo data */
2356                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2357                 COUNT_BYTES(bc);
2358         }
2359
2360         END_OF_SMB
2361
2362         return offset;
2363 }
2364
2365 static int
2366 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2367 {
2368         int an_len, pwlen;
2369         const char *an;
2370         guint8 wc;
2371         guint16 bc;
2372
2373         WORD_COUNT;
2374  
2375         BYTE_COUNT;
2376
2377         /* buffer format */
2378         CHECK_BYTE_COUNT(1);
2379         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2380         COUNT_BYTES(1);
2381
2382         /* Path */
2383         an = get_unicode_or_ascii_string(tvb, &offset,
2384                 pinfo, &an_len, FALSE, FALSE, &bc);
2385         if (an == NULL)
2386                 goto endofcommand;
2387         proto_tree_add_string(tree, hf_smb_path, tvb,
2388                 offset, an_len, an);
2389         COUNT_BYTES(an_len);
2390
2391         if (check_col(pinfo->cinfo, COL_INFO)) {
2392                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
2393         }
2394
2395         /* buffer format */
2396         CHECK_BYTE_COUNT(1);
2397         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2398         COUNT_BYTES(1);
2399
2400         /* password, ANSI */
2401         /* XXX - what if this runs past bc? */
2402         pwlen = tvb_strsize(tvb, offset);
2403         CHECK_BYTE_COUNT(pwlen);
2404         proto_tree_add_item(tree, hf_smb_password,
2405                 tvb, offset, pwlen, TRUE);
2406         COUNT_BYTES(pwlen);
2407
2408         /* buffer format */
2409         CHECK_BYTE_COUNT(1);
2410         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2411         COUNT_BYTES(1);
2412
2413         /* Service */
2414         an = get_unicode_or_ascii_string(tvb, &offset,
2415                 pinfo, &an_len, FALSE, FALSE, &bc);
2416         if (an == NULL)
2417                 goto endofcommand;
2418         proto_tree_add_string(tree, hf_smb_service, tvb,
2419                 offset, an_len, an);
2420         COUNT_BYTES(an_len);
2421
2422         END_OF_SMB
2423
2424         return offset;
2425 }
2426
2427 static int
2428 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2429 {
2430         guint8 wc;
2431         guint16 bc;
2432
2433         WORD_COUNT;
2434  
2435         /* Maximum Buffer Size */
2436         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2437         offset += 2;
2438
2439         /* tid */
2440         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2441         offset += 2;
2442
2443         BYTE_COUNT;
2444
2445         END_OF_SMB
2446
2447         return offset;
2448 }
2449  
2450
2451 static const true_false_string tfs_of_create = {
2452         "Create file if it does not exist",
2453         "Fail if file does not exist"
2454 };
2455 static const value_string of_open[] = {
2456         { 0,            "Fail if file exists"},
2457         { 1,            "Open file if it exists"},
2458         { 2,            "Truncate file if it exists"},
2459         {0, NULL}
2460 };
2461 static int
2462 dissect_open_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
2463 {
2464         guint16 mask;
2465         proto_item *item = NULL;
2466         proto_tree *tree = NULL;
2467
2468         mask = tvb_get_letohs(tvb, offset);
2469
2470         if(parent_tree){
2471                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2472                         "Open Function: 0x%04x", mask);
2473                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2474         }
2475
2476         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2477                 tvb, offset, 2, mask);
2478         proto_tree_add_uint(tree, hf_smb_open_function_open,
2479                 tvb, offset, 2, mask);
2480
2481         offset += 2;
2482
2483         return offset;
2484 }
2485
2486
2487 static const true_false_string tfs_mf_file = {
2488         "Target must be a file",
2489         "Target needn't be a file"
2490  };
2491 static const true_false_string tfs_mf_dir = {
2492         "Target must be a directory",
2493         "Target needn't be a directory"
2494 };
2495 static const true_false_string tfs_mf_verify = {
2496         "MUST verify all writes",
2497         "Don't have to verify writes"
2498 };
2499 static int
2500 dissect_move_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
2501 {
2502         guint16 mask;
2503         proto_item *item = NULL;
2504         proto_tree *tree = NULL;
2505
2506         mask = tvb_get_letohs(tvb, offset);
2507
2508         if(parent_tree){
2509                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2510                         "Flags: 0x%04x", mask);
2511                 tree = proto_item_add_subtree(item, ett_smb_move_flags);
2512         }
2513  
2514         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2515                 tvb, offset, 2, mask);
2516         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2517                 tvb, offset, 2, mask);
2518         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2519                 tvb, offset, 2, mask);
2520
2521         offset += 2;
2522
2523         return offset;
2524 }
2525
2526 static int
2527 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2528 {
2529         int fn_len;
2530         guint16 tid;
2531         guint16 bc;
2532         guint8 wc;
2533         const char *fn;
2534
2535         WORD_COUNT;
2536
2537         /* tid */
2538         tid = tvb_get_letohs(tvb, offset);
2539         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2540                 "TID (target): 0x%04x", tid);
2541         offset += 2;
2542
2543         /* open function */
2544         offset = dissect_open_function(tvb, pinfo, tree, offset);
2545
2546         /* move flags */
2547         offset = dissect_move_flags(tvb, pinfo, tree, offset);
2548
2549         BYTE_COUNT;
2550
2551         /* buffer format */
2552         CHECK_BYTE_COUNT(1);
2553         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2554         COUNT_BYTES(1);
2555
2556         /* file name */
2557         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2558                 FALSE, FALSE, &bc);
2559         if (fn == NULL)
2560                 goto endofcommand;
2561         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2562                 fn_len, fn, "Old File Name: %s", fn);
2563         COUNT_BYTES(fn_len);
2564
2565         if (check_col(pinfo->cinfo, COL_INFO)) {
2566                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2567         }
2568
2569         /* buffer format */
2570         CHECK_BYTE_COUNT(1);
2571         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2572         COUNT_BYTES(1);
2573
2574         /* file name */
2575         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2576                 FALSE, FALSE, &bc);
2577         if (fn == NULL)
2578                 goto endofcommand;
2579         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2580                 fn_len, fn, "New File Name: %s", fn);
2581         COUNT_BYTES(fn_len);
2582
2583         if (check_col(pinfo->cinfo, COL_INFO)) {
2584                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2585         }
2586
2587         END_OF_SMB
2588
2589         return offset;
2590 }
2591
2592 static int
2593 dissect_move_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2594 {
2595         int fn_len;
2596         const char *fn;
2597         guint8 wc;
2598         guint16 bc;
2599
2600         WORD_COUNT;
2601
2602         /* # of files moved */
2603         proto_tree_add_item(tree, hf_smb_move_files_moved, tvb, offset, 2, TRUE);
2604         offset += 2;
2605
2606         BYTE_COUNT;
2607
2608         /* buffer format */
2609         CHECK_BYTE_COUNT(1);
2610         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2611         COUNT_BYTES(1);
2612
2613         /* file name */
2614         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2615                 FALSE, FALSE, &bc);
2616         if (fn == NULL)
2617                 goto endofcommand;
2618         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2619                 fn);
2620         COUNT_BYTES(fn_len);
2621
2622         END_OF_SMB
2623
2624         return offset;
2625 }
2626
2627 static int
2628 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2629 {
2630         int fn_len;
2631         const char *fn;
2632         guint8 wc;
2633         guint16 bc;
2634
2635         WORD_COUNT;
2636
2637         /* desired access */
2638         offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
2639
2640         /* Search Attributes */
2641         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2642
2643         BYTE_COUNT;
2644
2645         /* buffer format */
2646         CHECK_BYTE_COUNT(1);
2647         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2648         COUNT_BYTES(1);
2649
2650         /* file name */
2651         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2652                 FALSE, FALSE, &bc);
2653         if (fn == NULL)
2654                 goto endofcommand;
2655         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2656                 fn);
2657         COUNT_BYTES(fn_len);
2658
2659         if (check_col(pinfo->cinfo, COL_INFO)) {
2660                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2661         }
2662
2663         END_OF_SMB
2664
2665         return offset;
2666 }
2667
2668 void
2669 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2670     int len, guint16 fid)
2671 {
2672         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2673         if (check_col(pinfo->cinfo, COL_INFO))
2674                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2675 }
2676
2677 static int
2678 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2679 {
2680         guint8 wc;
2681         guint16 bc;
2682         guint16 fid;
2683
2684         WORD_COUNT;
2685
2686         /* fid */
2687         fid = tvb_get_letohs(tvb, offset);
2688         add_fid(tvb, pinfo, tree, offset, 2, fid);
2689         offset += 2;
2690
2691         /* File Attributes */
2692         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2693
2694         /* last write time */
2695         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2696         
2697         /* File Size */
2698         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2699         offset += 4;
2700
2701         /* granted access */
2702         offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
2703
2704         BYTE_COUNT;
2705
2706         END_OF_SMB
2707
2708         return offset;
2709 }
2710
2711 static int
2712 dissect_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2713 {
2714         guint8 wc;
2715         guint16 bc;
2716         guint16 fid;
2717
2718         WORD_COUNT;
2719
2720         /* fid */
2721         fid = tvb_get_letohs(tvb, offset);
2722         add_fid(tvb, pinfo, tree, offset, 2, fid);
2723         offset += 2;
2724
2725         BYTE_COUNT;
2726
2727         END_OF_SMB
2728
2729         return offset;
2730 }
2731
2732 static int
2733 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2734 {
2735         int fn_len;
2736         const char *fn;
2737         guint8 wc;
2738         guint16 bc;
2739
2740         WORD_COUNT;
2741
2742         /* file attributes */
2743         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2744
2745         /* creation time */
2746         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
2747
2748         BYTE_COUNT;
2749
2750         /* buffer format */
2751         CHECK_BYTE_COUNT(1);
2752         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2753         COUNT_BYTES(1);
2754
2755         /* File Name */
2756         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2757                 FALSE, FALSE, &bc);
2758         if (fn == NULL)
2759                 goto endofcommand;
2760         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2761                 fn);
2762         COUNT_BYTES(fn_len);
2763
2764         if (check_col(pinfo->cinfo, COL_INFO)) {
2765                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2766         }
2767
2768         END_OF_SMB
2769
2770         return offset;
2771 }
2772
2773 static int
2774 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2775 {
2776         guint8 wc;
2777         guint16 bc, fid;
2778
2779         WORD_COUNT;
2780
2781         /* fid */
2782         fid = tvb_get_letohs(tvb, offset);
2783         add_fid(tvb, pinfo, tree, offset, 2, fid);
2784         offset += 2;
2785
2786         /* last write time */
2787         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2788
2789         BYTE_COUNT;
2790
2791         END_OF_SMB
2792
2793         return offset;
2794 }
2795
2796 static int
2797 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2798 {
2799         int fn_len;
2800         const char *fn;
2801         guint8 wc;
2802         guint16 bc;
2803
2804         WORD_COUNT;
2805
2806         /* search attributes */
2807         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2808
2809         BYTE_COUNT;
2810
2811         /* buffer format */
2812         CHECK_BYTE_COUNT(1);
2813         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2814         COUNT_BYTES(1);
2815
2816         /* file name */
2817         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2818                 FALSE, FALSE, &bc);
2819         if (fn == NULL)
2820                 goto endofcommand;
2821         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2822                 fn);
2823         COUNT_BYTES(fn_len);
2824
2825         if (check_col(pinfo->cinfo, COL_INFO)) {
2826                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2827         }
2828
2829         END_OF_SMB
2830
2831         return offset;
2832 }
2833
2834 static int
2835 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2836 {
2837         int fn_len;
2838         const char *fn;
2839         guint8 wc;
2840         guint16 bc;
2841
2842         WORD_COUNT;
2843
2844         /* search attributes */
2845         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2846
2847         BYTE_COUNT;
2848
2849         /* buffer format */
2850         CHECK_BYTE_COUNT(1);
2851         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2852         COUNT_BYTES(1);
2853
2854         /* old file name */
2855         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2856                 FALSE, FALSE, &bc);
2857         if (fn == NULL)
2858                 goto endofcommand;
2859         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
2860                 fn);
2861         COUNT_BYTES(fn_len);
2862
2863         if (check_col(pinfo->cinfo, COL_INFO)) {
2864                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2865         }
2866
2867         /* buffer format */
2868         CHECK_BYTE_COUNT(1);
2869         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2870         COUNT_BYTES(1);
2871
2872         /* file name */
2873         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2874                 FALSE, FALSE, &bc);
2875         if (fn == NULL)
2876                 goto endofcommand;
2877         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2878                 fn);
2879         COUNT_BYTES(fn_len);
2880
2881         if (check_col(pinfo->cinfo, COL_INFO)) {
2882                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2883         }
2884
2885         END_OF_SMB
2886
2887         return offset;
2888 }
2889
2890 static int
2891 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2892 {
2893         int fn_len;
2894         const char *fn;
2895         guint8 wc;
2896         guint16 bc;
2897
2898         WORD_COUNT;
2899
2900         /* search attributes */
2901         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2902  
2903     proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
2904     offset += 2;
2905
2906     proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
2907     offset += 4;
2908
2909         BYTE_COUNT;
2910
2911         /* buffer format */
2912         CHECK_BYTE_COUNT(1);
2913         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2914         COUNT_BYTES(1);
2915
2916         /* old file name */
2917         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2918                 FALSE, FALSE, &bc);
2919         if (fn == NULL)
2920                 goto endofcommand;
2921         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
2922                 fn);
2923         COUNT_BYTES(fn_len);
2924
2925         if (check_col(pinfo->cinfo, COL_INFO)) {
2926                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2927         }
2928
2929         /* buffer format */
2930         CHECK_BYTE_COUNT(1);
2931         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2932         COUNT_BYTES(1);
2933
2934         /* file name */
2935         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2936                 FALSE, FALSE, &bc);
2937         if (fn == NULL)
2938                 goto endofcommand;
2939         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2940                 fn);
2941         COUNT_BYTES(fn_len);
2942
2943         if (check_col(pinfo->cinfo, COL_INFO)) {
2944                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2945         }
2946
2947         END_OF_SMB
2948
2949         return offset;
2950 }
2951
2952
2953 static int
2954 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2955 {
2956         guint16 bc;
2957         guint8 wc;
2958         const char *fn;
2959         int fn_len;
2960
2961         WORD_COUNT;
2962
2963         BYTE_COUNT;
2964
2965         /* Buffer Format */
2966         CHECK_BYTE_COUNT(1);
2967         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2968         COUNT_BYTES(1);
2969
2970         /* File Name */
2971         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2972                 FALSE, FALSE, &bc);
2973         if (fn == NULL)
2974                 goto endofcommand;
2975         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2976                 fn);
2977         COUNT_BYTES(fn_len);
2978
2979         if (check_col(pinfo->cinfo, COL_INFO)) {
2980                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2981         }
2982
2983         END_OF_SMB
2984
2985         return offset;
2986 }
2987  
2988 static int
2989 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2990 {
2991         guint16 bc;
2992         guint8 wc;
2993
2994         WORD_COUNT;
2995
2996         /* File Attributes */
2997         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2998
2999         /* Last Write Time */
3000         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
3001
3002         /* File Size */
3003         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3004         offset += 4;
3005
3006         /* 10 reserved bytes */
3007         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3008         offset += 10;
3009
3010         BYTE_COUNT;
3011
3012         END_OF_SMB
3013
3014         return offset;
3015 }
3016
3017 static int
3018 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3019 {
3020         int fn_len;
3021         const char *fn;
3022         guint8 wc;
3023         guint16 bc;
3024
3025         WORD_COUNT;
3026
3027         /* file attributes */
3028         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
3029
3030         /* last write time */
3031         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
3032
3033         /* 10 reserved bytes */
3034         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3035         offset += 10;
3036
3037         BYTE_COUNT;
3038
3039         /* buffer format */
3040         CHECK_BYTE_COUNT(1);
3041         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3042         COUNT_BYTES(1);
3043
3044         /* file name */
3045         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3046                 FALSE, FALSE, &bc);
3047         if (fn == NULL)
3048                 goto endofcommand;
3049         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3050                 fn);
3051         COUNT_BYTES(fn_len);
3052
3053         if (check_col(pinfo->cinfo, COL_INFO)) {
3054                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3055         }
3056
3057         END_OF_SMB
3058
3059         return offset;
3060 }
3061
3062 static int
3063 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3064 {
3065         guint8 wc;
3066         guint16 bc;
3067         smb_info_t *si;
3068         unsigned int fid;
3069
3070         WORD_COUNT;
3071
3072         /* fid */
3073         fid = tvb_get_letohs(tvb, offset);
3074         add_fid(tvb, pinfo, tree, offset, 2, fid);
3075         offset += 2;
3076         if (!pinfo->fd->flags.visited) {
3077                 /* remember the FID for the processing of the response */
3078                 si = (smb_info_t *)pinfo->private_data;
3079                 si->sip->extra_info=(void *)fid;
3080         }
3081
3082         /* read count */
3083         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3084         offset += 2;
3085
3086         /* offset */
3087         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3088         offset += 4;
3089
3090         /* remaining */
3091         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3092         offset += 2;
3093
3094         BYTE_COUNT;
3095
3096         END_OF_SMB
3097
3098         return offset;
3099 }
3100
3101 int
3102 dissect_file_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3103 {
3104         int tvblen;
3105
3106         if(bc>datalen){
3107                 /* We have some initial padding bytes. */
3108                 /* XXX - use the data offset here instead? */
3109                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3110                         TRUE);
3111                 offset += bc-datalen;
3112                 bc = datalen;
3113         }
3114         tvblen = tvb_length_remaining(tvb, offset);
3115         if(bc>tvblen){
3116                 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);
3117                 offset += tvblen;
3118         } else {
3119                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3120                 offset += bc;
3121         }
3122         return offset;
3123 }
3124
3125 static int
3126 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3127     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
3128 {
3129         int tvblen;
3130         tvbuff_t *dcerpc_tvb;
3131
3132         if(bc>datalen){
3133                 /* We have some initial padding bytes. */
3134                 /* XXX - use the data offset here instead? */
3135                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3136                         TRUE);
3137                 offset += bc-datalen;
3138                 bc = datalen;
3139         }
3140         tvblen = tvb_length_remaining(tvb, offset);
3141         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
3142         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
3143         if(bc>tvblen)
3144                 offset += tvblen;
3145         else
3146                 offset += bc;
3147         return offset;
3148 }
3149
3150 static int
3151 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3152 {
3153         guint16 cnt=0, bc;
3154         guint8 wc;
3155         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3156         int fid=0;
3157
3158         WORD_COUNT;
3159
3160         /* read count */
3161         cnt = tvb_get_letohs(tvb, offset);
3162         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3163         offset += 2;
3164
3165         /* 8 reserved bytes */
3166         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3167         offset += 8;
3168
3169         /* If we have seen the request, then print which FID this refers to */
3170         /* first check if we have seen the request */
3171         if(si->sip != NULL && si->sip->frame_req>0){
3172                 fid=(int)si->sip->extra_info;
3173                 add_fid(tvb, pinfo, tree, 0, 0, fid);
3174         }
3175
3176         BYTE_COUNT;
3177
3178         /* buffer format */
3179         CHECK_BYTE_COUNT(1);
3180         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3181         COUNT_BYTES(1);
3182
3183         /* data len */
3184         CHECK_BYTE_COUNT(2);
3185         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3186         COUNT_BYTES(2);
3187
3188         /* another way to transport DCERPC over SMB is to skip Transaction completely and just
3189            read write */
3190         if(bc){
3191                 if(si->sip != NULL && si->sip->flags&SMB_SIF_TID_IS_IPC){
3192                         /* dcerpc call */
3193                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
3194                             top_tree, offset, bc, bc, fid);
3195                 } else {
3196                         /* ordinary file data, or we didn't see the request,
3197                            so we don't know whether this is a DCERPC call
3198                            or not */
3199                         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
3200                 }
3201                 bc = 0;
3202         }
3203
3204         END_OF_SMB
3205
3206         return offset;
3207 }
3208
3209 static int
3210 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3211 {
3212         guint16 cnt, bc;
3213         guint8 wc;
3214
3215         WORD_COUNT;
3216
3217         /* read count */
3218         cnt = tvb_get_letohs(tvb, offset);
3219         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3220         offset += 2;
3221
3222         /* 8 reserved bytes */
3223         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3224         offset += 8;
3225
3226         BYTE_COUNT;
3227
3228         /* buffer format */
3229         CHECK_BYTE_COUNT(1);
3230         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3231         COUNT_BYTES(1);
3232
3233         /* data len */
3234         CHECK_BYTE_COUNT(2);
3235         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3236         COUNT_BYTES(2);
3237
3238         END_OF_SMB
3239
3240         return offset;
3241 }
3242
3243
3244 static int
3245 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3246 {
3247         guint32 ofs=0;
3248         guint16 cnt=0, bc, fid=0;
3249         guint8 wc;
3250         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3251
3252         WORD_COUNT;
3253
3254         /* fid */
3255         fid = tvb_get_letohs(tvb, offset);
3256         add_fid(tvb, pinfo, tree, offset, 2, fid);
3257         offset += 2;
3258
3259         /* write count */
3260         cnt = tvb_get_letohs(tvb, offset);
3261         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3262         offset += 2;
3263
3264         /* offset */
3265         ofs = tvb_get_letohl(tvb, offset);
3266         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3267         offset += 4;
3268
3269         if (check_col(pinfo->cinfo, COL_INFO))
3270                 col_append_fstr(pinfo->cinfo, COL_INFO, 
3271                                 ", %d byte%s at offset %d", cnt, 
3272                                 (cnt == 1) ? "" : "s", ofs);
3273
3274         /* remaining */
3275         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3276         offset += 2;
3277
3278         BYTE_COUNT;
3279
3280         /* buffer format */
3281         CHECK_BYTE_COUNT(1);
3282         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3283         COUNT_BYTES(1);
3284
3285         /* data len */
3286         CHECK_BYTE_COUNT(2);
3287         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3288         COUNT_BYTES(2);
3289
3290         if (bc != 0) {
3291                 if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
3292                         /* dcerpc call */
3293                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
3294                             top_tree, offset, bc, bc, fid);
3295                 } else {
3296                         /* ordinary file data */
3297                         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
3298                 }
3299                 bc = 0;
3300         }
3301
3302         END_OF_SMB
3303
3304         return offset;
3305 }
3306  
3307 static int
3308 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3309 {
3310         guint8 wc;
3311         guint16 bc, cnt;
3312
3313         WORD_COUNT;
3314
3315         /* write count */
3316         cnt = tvb_get_letohs(tvb, offset);
3317         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3318         offset += 2;
3319
3320         if (check_col(pinfo->cinfo, COL_INFO))
3321                 col_append_fstr(pinfo->cinfo, COL_INFO, 
3322                                 ", %d byte%s", cnt, (cnt == 1) ? "" : "s");
3323
3324         BYTE_COUNT;
3325
3326         END_OF_SMB
3327
3328         return offset;
3329 }
3330
3331 static int
3332 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3333 {
3334         guint8 wc;
3335         guint16 bc, fid;
3336
3337         WORD_COUNT;
3338
3339         /* fid */
3340         fid = tvb_get_letohs(tvb, offset);
3341         add_fid(tvb, pinfo, tree, offset, 2, fid);
3342         offset += 2;
3343
3344         /* lock count */
3345         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3346         offset += 4;
3347
3348         /* offset */
3349         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3350         offset += 4;
3351
3352         BYTE_COUNT;
3353
3354         END_OF_SMB
3355
3356         return offset;
3357 }
3358
3359 static int
3360 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3361 {
3362         int fn_len;
3363         const char *fn;
3364         guint8 wc;
3365         guint16 bc;
3366
3367         WORD_COUNT;
3368
3369         /* 2 reserved bytes */
3370         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3371         offset += 2;
3372
3373         /* Creation time */
3374         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
3375
3376         BYTE_COUNT;
3377
3378         /* buffer format */
3379         CHECK_BYTE_COUNT(1);
3380         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3381         COUNT_BYTES(1);
3382
3383         /* directory name */
3384         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3385                 FALSE, FALSE, &bc);
3386         if (fn == NULL)
3387                 goto endofcommand;
3388         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3389                 fn);
3390         COUNT_BYTES(fn_len);
3391
3392         if (check_col(pinfo->cinfo, COL_INFO)) {
3393                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3394         }
3395
3396         END_OF_SMB
3397
3398         return offset;
3399 }
3400
3401 static int
3402 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3403 {
3404         int fn_len;
3405         const char *fn;
3406         guint8 wc;
3407         guint16 bc, fid;
3408
3409         WORD_COUNT;
3410
3411         /* fid */
3412         fid = tvb_get_letohs(tvb, offset);
3413         add_fid(tvb, pinfo, tree, offset, 2, fid);
3414         offset += 2;
3415
3416         BYTE_COUNT;
3417
3418         /* buffer format */
3419         CHECK_BYTE_COUNT(1);
3420         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3421         COUNT_BYTES(1);
3422
3423         /* file name */
3424         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3425                 FALSE, FALSE, &bc);
3426         if (fn == NULL)
3427                 goto endofcommand;
3428         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3429                 fn);
3430         COUNT_BYTES(fn_len);
3431
3432         END_OF_SMB
3433
3434         return offset;
3435 }
3436
3437 static const value_string seek_mode_vals[] = {
3438         {0,     "From Start Of File"},
3439         {1,     "From Current Position"},
3440         {2,     "From End Of File"},
3441         {0,     NULL}
3442 };
3443
3444 static int
3445 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3446 {
3447         guint8 wc;
3448         guint16 bc, fid;
3449
3450         WORD_COUNT;
3451
3452         /* fid */
3453         fid = tvb_get_letohs(tvb, offset);
3454         add_fid(tvb, pinfo, tree, offset, 2, fid);
3455         offset += 2;
3456
3457         /* Seek Mode */
3458         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3459         offset += 2;
3460
3461         /* offset */
3462         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3463         offset += 4;
3464
3465         BYTE_COUNT;
3466
3467         END_OF_SMB
3468
3469         return offset;
3470 }
3471
3472 static int
3473 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3474 {
3475         guint8 wc;
3476         guint16 bc;
3477
3478         WORD_COUNT;
3479
3480         /* offset */
3481         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3482         offset += 4;
3483
3484         BYTE_COUNT;
3485
3486         END_OF_SMB
3487
3488         return offset;
3489 }
3490  
3491 static int
3492 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3493 {
3494         guint8 wc;
3495         guint16 bc, fid;
3496
3497         WORD_COUNT;
3498
3499         /* fid */
3500         fid = tvb_get_letohs(tvb, offset);
3501         add_fid(tvb, pinfo, tree, offset, 2, fid);
3502         offset += 2;
3503
3504         /* create time */
3505         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3506                 hf_smb_create_time,
3507                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3508
3509         /* access time */
3510         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3511                 hf_smb_access_time,
3512                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3513
3514         /* last write time */
3515         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3516                 hf_smb_last_write_time,
3517                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3518
3519         BYTE_COUNT;
3520
3521         END_OF_SMB
3522
3523         return offset;
3524 }
3525
3526 static int
3527 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3528 {
3529         guint8 wc;
3530         guint16 bc;
3531
3532         WORD_COUNT;
3533
3534         /* create time */
3535         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3536                 hf_smb_create_time,
3537                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3538
3539         /* access time */
3540         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3541                 hf_smb_access_time,
3542                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3543
3544         /* last write time */
3545         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3546                 hf_smb_last_write_time,
3547                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3548
3549         /* data size */
3550         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3551         offset += 4;
3552
3553         /* allocation size */
3554         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3555         offset += 4;
3556
3557         /* File Attributes */
3558         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
3559
3560         BYTE_COUNT;
3561
3562         END_OF_SMB
3563
3564         return offset;
3565 }
3566
3567 static int
3568 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3569 {
3570         guint8 wc;
3571         guint16 cnt=0;
3572         guint16 bc, fid;
3573
3574         WORD_COUNT;
3575
3576         /* fid */
3577         fid = tvb_get_letohs(tvb, offset);
3578         add_fid(tvb, pinfo, tree, offset, 2, fid);
3579         offset += 2;
3580
3581         /* write count */
3582         cnt = tvb_get_letohs(tvb, offset);
3583         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3584         offset += 2;
3585
3586         /* offset */
3587         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3588         offset += 4;
3589
3590         /* last write time */
3591         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
3592         
3593         if(wc==12){
3594                 /* 12 reserved bytes */
3595                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3596                 offset += 12;
3597         }
3598
3599         BYTE_COUNT;
3600
3601         /* 1 pad byte */
3602         CHECK_BYTE_COUNT(1);
3603         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3604         COUNT_BYTES(1);
3605         
3606         offset = dissect_file_data(tvb, pinfo, tree, offset, cnt, cnt);
3607         bc = 0; /* XXX */
3608
3609         END_OF_SMB
3610
3611         return offset;
3612 }
3613  
3614 static int
3615 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3616 {
3617         guint8 wc;
3618         guint16 bc;
3619
3620         WORD_COUNT;
3621
3622         /* write count */
3623         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3624         offset += 2;
3625
3626         BYTE_COUNT;
3627
3628         END_OF_SMB
3629
3630         return offset;
3631 }
3632
3633 static int
3634 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3635 {
3636         guint8 wc;
3637         guint16 bc, fid;
3638         guint32 to;
3639
3640         WORD_COUNT;
3641
3642         /* fid */
3643         fid = tvb_get_letohs(tvb, offset);
3644         add_fid(tvb, pinfo, tree, offset, 2, fid);
3645         offset += 2;
3646
3647         /* offset */
3648         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3649         offset += 4;
3650
3651         /* max count */
3652         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3653         offset += 2;
3654
3655         /* min count */
3656         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3657         offset += 2;
3658
3659         /* timeout */
3660         to = tvb_get_letohl(tvb, offset);
3661         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3662         offset += 4;
3663
3664         /* 2 reserved bytes */
3665         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3666         offset += 2;
3667
3668         if(wc==10){
3669                 /* high offset */
3670                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3671                 offset += 4;
3672         }
3673
3674         BYTE_COUNT;
3675
3676         END_OF_SMB
3677
3678         return offset;
3679 }
3680
3681 static int
3682 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3683 {
3684         guint8 wc;
3685         guint16 bc;
3686
3687         WORD_COUNT;
3688
3689         /* units */
3690         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3691         offset += 2;
3692
3693         /* bpu */
3694         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3695         offset += 2;
3696
3697         /* block size */
3698         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3699         offset += 2;
3700
3701         /* free units */
3702         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3703         offset += 2;
3704
3705         /* 2 reserved bytes */
3706         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3707         offset += 2;
3708
3709         BYTE_COUNT;
3710
3711         END_OF_SMB
3712
3713         return offset;
3714 }
3715
3716 static int
3717 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3718 {
3719         guint8 wc;
3720         guint16 bc, fid;
3721
3722         WORD_COUNT;
3723
3724         /* fid */
3725         fid = tvb_get_letohs(tvb, offset);
3726         add_fid(tvb, pinfo, tree, offset, 2, fid);
3727         offset += 2;
3728
3729         /* offset */
3730         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3731         offset += 4;
3732
3733         /* max count */
3734         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3735         offset += 2;
3736
3737         /* min count */
3738         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3739         offset += 2;
3740
3741         /* 6 reserved bytes */
3742         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
3743         offset += 6;
3744
3745         BYTE_COUNT;
3746
3747         END_OF_SMB
3748
3749         return offset;
3750 }
3751
3752 static int
3753 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3754 {
3755         guint16 datalen=0, bc;
3756         guint8 wc;
3757
3758         WORD_COUNT;
3759
3760         /* offset */
3761         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3762         offset += 4;
3763
3764         /* count */
3765         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3766         offset += 2;
3767
3768         /* 2 reserved bytes */
3769         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3770         offset += 2;
3771
3772         /* data compaction mode */
3773         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
3774         offset += 2;
3775
3776         /* 2 reserved bytes */
3777         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3778         offset += 2;
3779
3780         /* data len */
3781         datalen = tvb_get_letohs(tvb, offset);
3782         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3783         offset += 2;
3784
3785         /* data offset */
3786         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3787         offset += 2;
3788
3789         BYTE_COUNT;
3790
3791         /* file data */
3792         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3793         bc = 0;
3794
3795         END_OF_SMB
3796
3797         return offset;
3798 }
3799
3800
3801 static const true_false_string tfs_write_mode_write_through = {
3802         "WRITE THROUGH requested",
3803         "Write through not requested"
3804 };
3805 static const true_false_string tfs_write_mode_return_remaining = {
3806         "RETURN REMAINING (pipe/dev) requested",
3807         "DON'T return remaining (pipe/dev)"
3808 };
3809 static const true_false_string tfs_write_mode_raw = {
3810         "Use WriteRawNamedPipe (pipe)",
3811         "DON'T use WriteRawNamedPipe (pipe)"
3812 };
3813 static const true_false_string tfs_write_mode_message_start = {
3814         "This is the START of a MESSAGE (pipe)",
3815         "This is NOT the start of a message (pipe)"
3816 };
3817 static const true_false_string tfs_write_mode_connectionless = {
3818         "CONNECTIONLESS mode requested",
3819         "Connectionless mode NOT requested"
3820 };
3821 static int
3822 dissect_write_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int bm)
3823 {
3824         guint16 mask;
3825         proto_item *item = NULL;
3826         proto_tree *tree = NULL;
3827
3828         mask = tvb_get_letohs(tvb, offset);
3829
3830         if(parent_tree){
3831                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
3832                         "Write Mode: 0x%04x", mask);
3833                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
3834         }
3835
3836         if(bm&0x0080){
3837                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
3838                         tvb, offset, 2, mask);
3839         }
3840         if(bm&0x0008){
3841                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
3842                         tvb, offset, 2, mask);
3843         }
3844         if(bm&0x0004){
3845                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
3846                         tvb, offset, 2, mask);
3847         }
3848         if(bm&0x0002){
3849                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
3850                         tvb, offset, 2, mask);
3851         }
3852         if(bm&0x0001){
3853                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
3854                         tvb, offset, 2, mask);
3855         }
3856
3857         offset += 2;
3858         return offset;
3859 }
3860
3861 static int
3862 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3863 {
3864         guint32 to;
3865         guint16 datalen=0, bc, fid;
3866         guint8 wc;
3867
3868         WORD_COUNT;
3869
3870         /* fid */
3871         fid = tvb_get_letohs(tvb, offset);
3872         add_fid(tvb, pinfo, tree, offset, 2, fid);
3873         offset += 2;
3874
3875         /* total data length */
3876         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
3877         offset += 2;
3878
3879         /* 2 reserved bytes */
3880         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3881         offset += 2;
3882
3883         /* offset */
3884         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3885         offset += 4;
3886
3887         /* timeout */
3888         to = tvb_get_letohl(tvb, offset);
3889         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3890         offset += 4;
3891
3892         /* mode */
3893         offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x0003);
3894
3895         /* 4 reserved bytes */
3896         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
3897         offset += 4;
3898
3899         /* data len */
3900         datalen = tvb_get_letohs(tvb, offset);
3901         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3902         offset += 2;
3903
3904         /* data offset */
3905         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3906         offset += 2;
3907
3908         BYTE_COUNT;
3909
3910         /* file data */
3911         /* XXX - use the data offset to determine where the data starts? */
3912         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3913         bc = 0;
3914
3915         END_OF_SMB
3916
3917         return offset;
3918 }
3919  
3920 static int
3921 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3922 {
3923         guint8 wc;
3924         guint16 bc;
3925
3926         WORD_COUNT;
3927
3928         /* remaining */
3929         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3930         offset += 2;
3931
3932         BYTE_COUNT;
3933
3934         END_OF_SMB
3935
3936         return offset;
3937 }
3938
3939 static int
3940 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3941 {
3942         guint32 to;
3943         guint16 datalen=0, bc, fid;
3944         guint8 wc;
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         /* total data length */
3954         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
3955         offset += 2;
3956
3957         /* 2 reserved bytes */
3958         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3959         offset += 2;
3960
3961         /* offset */
3962         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3963         offset += 4;
3964
3965         /* timeout */
3966         to = tvb_get_letohl(tvb, offset);
3967         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3968         offset += 4;
3969
3970         /* mode */
3971         offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x0083);
3972
3973         /* request mask */
3974         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
3975         offset += 4;
3976         
3977         /* data len */
3978         datalen = tvb_get_letohs(tvb, offset);
3979         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3980         offset += 2;
3981
3982         /* data offset */
3983         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3984         offset += 2;
3985
3986         BYTE_COUNT;
3987
3988         /* file data */
3989         /* XXX - use the data offset to determine where the data starts? */
3990         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3991         bc = 0;
3992
3993         END_OF_SMB
3994
3995         return offset;
3996 }
3997  
3998 static int
3999 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4000 {
4001         guint8 wc;
4002         guint16 bc;
4003
4004         WORD_COUNT;
4005
4006         /* response mask */
4007         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
4008         offset += 4;
4009         
4010         BYTE_COUNT;
4011
4012         END_OF_SMB
4013
4014         return offset;
4015 }
4016
4017 static int
4018 dissect_sid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4019 {
4020         guint8 wc;
4021         guint16 bc;
4022
4023         WORD_COUNT;
4024
4025         /* sid */
4026         proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
4027         offset += 2;
4028
4029         BYTE_COUNT;
4030
4031         END_OF_SMB
4032
4033         return offset;
4034 }
4035
4036 static int
4037 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
4038     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
4039 {
4040         proto_item *item = NULL;
4041         proto_tree *tree = NULL;
4042         int fn_len;
4043         const char *fn;
4044         char fname[11+1];
4045
4046         if(parent_tree){
4047                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
4048                         "Resume Key");
4049                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
4050         }
4051
4052         /* reserved byte */
4053         CHECK_BYTE_COUNT_SUBR(1);
4054         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4055         COUNT_BYTES_SUBR(1);
4056
4057         /* file name */
4058         fn_len = 11;
4059         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4060                 TRUE, TRUE, bcp);
4061         CHECK_STRING_SUBR(fn);
4062         /* ensure that it's null-terminated */
4063         strncpy(fname, fn, 11);
4064         fname[11] = '\0';
4065         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
4066                 fname);
4067         COUNT_BYTES_SUBR(fn_len);
4068
4069         /* server cookie */
4070         CHECK_BYTE_COUNT_SUBR(5);
4071         proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
4072         COUNT_BYTES_SUBR(5);
4073
4074         /* client cookie */
4075         CHECK_BYTE_COUNT_SUBR(4);
4076         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
4077         COUNT_BYTES_SUBR(4);
4078
4079         *trunc = FALSE;
4080         return offset;
4081 }
4082
4083 static int
4084 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
4085     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
4086 {
4087         proto_item *item = NULL;
4088         proto_tree *tree = NULL;
4089         int fn_len;
4090         const char *fn;
4091         char fname[13+1];
4092
4093         if(parent_tree){
4094                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
4095                         "Directory Information");
4096                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
4097         }
4098
4099         /* resume key */
4100         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp, trunc);
4101         if (*trunc)
4102                 return offset;
4103
4104         /* File Attributes */
4105         CHECK_BYTE_COUNT_SUBR(1);
4106         offset = dissect_dir_info_file_attributes(tvb, pinfo, tree, offset);
4107         *bcp -= 1;
4108
4109         /* last write time */
4110         CHECK_BYTE_COUNT_SUBR(4);
4111         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
4112                 hf_smb_last_write_time,
4113                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
4114                 TRUE);
4115         *bcp -= 4;
4116
4117         /* File Size */
4118         CHECK_BYTE_COUNT_SUBR(4);
4119         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4120         COUNT_BYTES_SUBR(4);
4121
4122         /* file name */
4123         fn_len = 13;
4124         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4125                 TRUE, TRUE, bcp);
4126         CHECK_STRING_SUBR(fn);
4127         /* ensure that it's null-terminated */
4128         strncpy(fname, fn, 13);
4129         fname[13] = '\0';
4130         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4131                 fname);
4132         COUNT_BYTES_SUBR(fn_len);
4133
4134         *trunc = FALSE;
4135         return offset;
4136 }
4137
4138
4139 static int
4140 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4141 {
4142         int fn_len;
4143         const char *fn;
4144         guint16 rkl;
4145         guint8 wc;
4146         guint16 bc;
4147         gboolean trunc;
4148
4149         WORD_COUNT;
4150
4151         /* max count */
4152         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4153         offset += 2;
4154
4155         /* Search Attributes */
4156         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
4157
4158         BYTE_COUNT;
4159
4160         /* buffer format */
4161         CHECK_BYTE_COUNT(1);
4162         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4163         COUNT_BYTES(1);
4164
4165         /* file name */
4166         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4167                 TRUE, FALSE, &bc);
4168         if (fn == NULL)
4169                 goto endofcommand;
4170         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4171                 fn);
4172         COUNT_BYTES(fn_len);
4173
4174         if (check_col(pinfo->cinfo, COL_INFO)) {
4175                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", fn);
4176         }
4177
4178         /* buffer format */
4179         CHECK_BYTE_COUNT(1);
4180         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4181         COUNT_BYTES(1);
4182
4183         /* resume key length */
4184         CHECK_BYTE_COUNT(2);
4185         rkl = tvb_get_letohs(tvb, offset);
4186         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
4187         COUNT_BYTES(2);
4188
4189         /* resume key */
4190         if(rkl){
4191                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
4192                     &bc, &trunc);
4193                 if (trunc)
4194                         goto endofcommand;
4195         }
4196
4197         END_OF_SMB
4198
4199         return offset;
4200 }
4201
4202 static int
4203 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4204 {
4205         guint16 count=0;
4206         guint8 wc;
4207         guint16 bc;
4208         gboolean trunc;
4209
4210         WORD_COUNT;
4211
4212         /* count */
4213         count = tvb_get_letohs(tvb, offset);
4214         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
4215         offset += 2;
4216
4217         BYTE_COUNT;
4218
4219         /* buffer format */
4220         CHECK_BYTE_COUNT(1);
4221         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4222         COUNT_BYTES(1);
4223
4224         /* data len */
4225         CHECK_BYTE_COUNT(2);
4226         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4227         COUNT_BYTES(2);
4228
4229         while(count--){
4230                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
4231                     &bc, &trunc);
4232                 if (trunc)
4233                         goto endofcommand;
4234         }
4235
4236         END_OF_SMB
4237
4238         return offset;
4239 }
4240
4241 static const value_string locking_ol_vals[] = {
4242         {0,     "Client is not holding oplock on this file"},
4243         {1,     "Level 2 oplock currently held by client"},
4244         {0, NULL}
4245 };
4246
4247 static const true_false_string tfs_lock_type_large = {
4248         "Large file locking format requested",
4249         "Large file locking format not requested"
4250 };
4251 static const true_false_string tfs_lock_type_cancel = {
4252         "Cancel outstanding lock request",
4253         "Don't cancel outstanding lock request"
4254 };
4255 static const true_false_string tfs_lock_type_change = {
4256         "Change lock type",
4257         "Don't change lock type"
4258 };
4259 static const true_false_string tfs_lock_type_oplock = {
4260         "This is an oplock break notification/response",
4261         "This is not an oplock break notification/response"
4262 };
4263 static const true_false_string tfs_lock_type_shared = {
4264         "This is a shared lock",
4265         "This is an exclusive lock"
4266 };
4267 static int
4268 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4269 {
4270         guint8  wc, cmd=0xff, lt=0;
4271         guint16 andxoffset=0, un=0, ln=0, bc, fid;
4272         guint32 to;
4273         proto_item *litem = NULL;
4274         proto_tree *ltree = NULL;
4275         proto_item *it = NULL;
4276         proto_tree *tr = NULL;
4277         int old_offset = offset;
4278
4279         WORD_COUNT;
4280
4281         /* next smb command */
4282         cmd = tvb_get_guint8(tvb, offset);
4283         if(cmd!=0xff){
4284                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4285         } else {
4286                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4287         }
4288         offset += 1;
4289
4290         /* reserved byte */
4291         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4292         offset += 1;
4293
4294         /* andxoffset */
4295         andxoffset = tvb_get_letohs(tvb, offset);
4296         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4297         offset += 2;
4298
4299         /* fid */
4300         fid = tvb_get_letohs(tvb, offset);
4301         add_fid(tvb, pinfo, tree, offset, 2, fid);
4302         offset += 2;
4303
4304         /* lock type */
4305         lt = tvb_get_guint8(tvb, offset);
4306         if(tree){
4307                 litem = proto_tree_add_text(tree, tvb, offset, 1,
4308                         "Lock Type: 0x%02x", lt);
4309                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
4310         }
4311         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
4312                 tvb, offset, 1, lt);
4313         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
4314                 tvb, offset, 1, lt);
4315         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
4316                 tvb, offset, 1, lt);
4317         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
4318                 tvb, offset, 1, lt);
4319         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
4320                 tvb, offset, 1, lt);
4321         offset += 1;
4322
4323         /* oplock level */
4324         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
4325         offset += 1;
4326
4327         /* timeout */
4328         to = tvb_get_letohl(tvb, offset);
4329         if (to == 0)
4330                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
4331         else if (to == 0xffffffff)
4332                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
4333         else
4334                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4335         offset += 4;
4336
4337         /* number of unlocks */
4338         un = tvb_get_letohs(tvb, offset);
4339         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
4340         offset += 2;
4341
4342         /* number of locks */
4343         ln = tvb_get_letohs(tvb, offset);
4344         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
4345         offset += 2;
4346
4347         BYTE_COUNT;
4348
4349         /* unlocks */
4350         if(un){
4351                 old_offset = offset;
4352
4353                 it = proto_tree_add_text(tree, tvb, offset, -1,
4354                         "Unlocks");
4355                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
4356                 while(un--){
4357                         proto_item *litem = NULL;
4358                         proto_tree *ltree = NULL;
4359                         if(lt&0x10){
4360                                 /* large lock format */
4361                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4362                                         "Unlock");
4363                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4364                                 
4365                                 /* PID */
4366                                 CHECK_BYTE_COUNT(2);
4367                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4368                                 COUNT_BYTES(2);
4369
4370                                 /* 2 reserved bytes */
4371                                 CHECK_BYTE_COUNT(2);
4372                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4373                                 COUNT_BYTES(2);
4374
4375                                 /* offset */
4376                                 CHECK_BYTE_COUNT(8);
4377                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4378                                 COUNT_BYTES(8);
4379
4380                                 /* length */
4381                                 CHECK_BYTE_COUNT(8);
4382                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4383                                 COUNT_BYTES(8);
4384                         } else {
4385                                 /* normal lock format */
4386                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4387                                         "Unlock");
4388                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4389                                 
4390                                 /* PID */
4391                                 CHECK_BYTE_COUNT(2);
4392                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4393                                 COUNT_BYTES(2);
4394
4395                                 /* offset */
4396                                 CHECK_BYTE_COUNT(4);
4397                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4398                                 COUNT_BYTES(4);
4399
4400                                 /* lock count */
4401                                 CHECK_BYTE_COUNT(4);
4402                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4403                                 COUNT_BYTES(4);
4404                         }
4405                 }
4406                 proto_item_set_len(it, offset-old_offset);
4407                 it = NULL;
4408         }
4409
4410         /* locks */
4411         if(ln){
4412                 old_offset = offset;
4413
4414                 it = proto_tree_add_text(tree, tvb, offset, -1,
4415                         "Locks");
4416                 tr = proto_item_add_subtree(it, ett_smb_locks);
4417                 while(ln--){
4418                         proto_item *litem = NULL;
4419                         proto_tree *ltree = NULL;
4420                         if(lt&0x10){
4421                                 /* large lock format */
4422                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4423                                         "Lock");
4424                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
4425                                 
4426                                 /* PID */
4427                                 CHECK_BYTE_COUNT(2);
4428                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4429                                 COUNT_BYTES(2);
4430
4431                                 /* 2 reserved bytes */
4432                                 CHECK_BYTE_COUNT(2);
4433                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4434                                 COUNT_BYTES(2);
4435
4436                                 /* offset */
4437                                 CHECK_BYTE_COUNT(8);
4438                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4439                                 COUNT_BYTES(8);
4440
4441                                 /* length */
4442                                 CHECK_BYTE_COUNT(8);
4443                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4444                                 COUNT_BYTES(8);
4445                         } else {
4446                                 /* normal lock format */
4447                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4448                                         "Unlock");
4449                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4450                                 
4451                                 /* PID */
4452                                 CHECK_BYTE_COUNT(2);
4453                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4454                                 COUNT_BYTES(2);
4455
4456                                 /* offset */
4457                                 CHECK_BYTE_COUNT(4);
4458                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4459                                 COUNT_BYTES(4);
4460
4461                                 /* lock count */
4462                                 CHECK_BYTE_COUNT(4);
4463                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4464                                 COUNT_BYTES(4);
4465                         }
4466                 }
4467                 proto_item_set_len(it, offset-old_offset);
4468                 it = NULL;
4469         }
4470
4471         END_OF_SMB
4472
4473         if (it != NULL) {
4474                 /*
4475                  * We ran out of byte count in the middle of dissecting
4476                  * the locks or the unlocks; set the site of the item
4477                  * we were dissecting.
4478                  */
4479                 proto_item_set_len(it, offset-old_offset);
4480         }
4481
4482         /* call AndXCommand (if there are any) */
4483         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4484
4485         return offset;
4486 }
4487
4488 static int
4489 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4490 {
4491         guint8  wc, cmd=0xff;
4492         guint16 andxoffset=0;
4493         guint16 bc;
4494
4495         WORD_COUNT;
4496
4497         /* next smb command */
4498         cmd = tvb_get_guint8(tvb, offset);
4499         if(cmd!=0xff){
4500                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4501         } else {
4502                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4503         }
4504         offset += 1;
4505
4506         /* reserved byte */
4507         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4508         offset += 1;
4509
4510         /* andxoffset */
4511         andxoffset = tvb_get_letohs(tvb, offset);
4512         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4513         offset += 2;
4514
4515         BYTE_COUNT;
4516
4517         END_OF_SMB
4518
4519         /* call AndXCommand (if there are any) */
4520         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4521
4522         return offset;
4523 }
4524
4525
4526 static const value_string oa_open_vals[] = {
4527         { 0,            "No action taken?"},
4528         { 1,            "The file existed and was opened"},
4529         { 2,            "The file did not exist but was created"},
4530         { 3,            "The file existed and was truncated"},
4531         {0,     NULL}
4532 };
4533 static const true_false_string tfs_oa_lock = {
4534         "File is currently opened only by this user",
4535         "File is opened by another user (or mode not supported by server)"
4536 };
4537 static int
4538 dissect_open_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
4539 {
4540         guint16 mask;
4541         proto_item *item = NULL;
4542         proto_tree *tree = NULL;
4543
4544         mask = tvb_get_letohs(tvb, offset);
4545
4546         if(parent_tree){
4547                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4548                         "Action: 0x%04x", mask);
4549                 tree = proto_item_add_subtree(item, ett_smb_open_action);
4550         }
4551
4552         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
4553                 tvb, offset, 2, mask);
4554         proto_tree_add_uint(tree, hf_smb_open_action_open,
4555                 tvb, offset, 2, mask);
4556
4557         offset += 2;
4558
4559         return offset;
4560 }
4561
4562 static const true_false_string tfs_open_flags_add_info = {
4563         "Additional information requested",
4564         "Additional information not requested"
4565 };
4566 static const true_false_string tfs_open_flags_ex_oplock = {
4567         "Exclusive oplock requested",
4568         "Exclusive oplock not requested"
4569 };
4570 static const true_false_string tfs_open_flags_batch_oplock = {
4571         "Batch oplock requested",
4572         "Batch oplock not requested"
4573 };
4574 static const true_false_string tfs_open_flags_ealen = {
4575         "Total length of EAs requested",
4576         "Total length of EAs not requested"
4577 };
4578 static int
4579 dissect_open_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int bm)
4580 {
4581         guint16 mask;
4582         proto_item *item = NULL;
4583         proto_tree *tree = NULL;
4584
4585         mask = tvb_get_letohs(tvb, offset);
4586
4587         if(parent_tree){
4588                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4589                         "Flags: 0x%04x", mask);
4590                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
4591         }
4592
4593         if(bm&0x0001){
4594                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
4595                         tvb, offset, 2, mask);
4596         }
4597         if(bm&0x0002){
4598                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
4599                         tvb, offset, 2, mask);
4600         }
4601         if(bm&0x0004){
4602                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
4603                         tvb, offset, 2, mask);
4604         }
4605         if(bm&0x0008){
4606                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
4607                         tvb, offset, 2, mask);
4608         }
4609
4610         offset += 2;
4611
4612         return offset;
4613 }
4614
4615 static const value_string filetype_vals[] = {
4616         { 0,            "Disk file or directory"},
4617         { 1,            "Named pipe in byte mode"},
4618         { 2,            "Named pipe in message mode"},
4619         { 3,            "Spooled printer"},
4620         {0, NULL}
4621 };
4622 static int
4623 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4624 {
4625         guint8  wc, cmd=0xff;
4626         guint16 andxoffset=0, bc;
4627         int fn_len;
4628         const char *fn;
4629
4630         WORD_COUNT;
4631
4632         /* next smb command */
4633         cmd = tvb_get_guint8(tvb, offset);
4634         if(cmd!=0xff){
4635                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4636         } else {
4637                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4638         }
4639         offset += 1;
4640
4641         /* reserved byte */
4642         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4643         offset += 1;
4644
4645         /* andxoffset */
4646         andxoffset = tvb_get_letohs(tvb, offset);
4647         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4648         offset += 2;
4649
4650         /* open flags */
4651         offset = dissect_open_flags(tvb, pinfo, tree, offset, 0x0007);
4652
4653         /* desired access */
4654         offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
4655
4656         /* Search Attributes */
4657         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
4658
4659         /* File Attributes */
4660         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
4661
4662         /* creation time */
4663         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
4664         
4665         /* open function */
4666         offset = dissect_open_function(tvb, pinfo, tree, offset);
4667
4668         /* allocation size */
4669         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
4670         offset += 4;
4671
4672         /* 8 reserved bytes */
4673         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4674         offset += 8;
4675
4676         BYTE_COUNT;
4677
4678         /* file name */
4679         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4680                 FALSE, FALSE, &bc);
4681         if (fn == NULL)
4682                 goto endofcommand;
4683         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4684                 fn);
4685         COUNT_BYTES(fn_len);
4686
4687         if (check_col(pinfo->cinfo, COL_INFO)) {
4688                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
4689         }
4690
4691         END_OF_SMB
4692
4693         /* call AndXCommand (if there are any) */
4694         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4695
4696         return offset;
4697 }
4698
4699 static const true_false_string tfs_ipc_state_nonblocking = {
4700         "Reads/writes return immediately if no data available",
4701         "Reads/writes block if no data available"
4702 };
4703 static const value_string ipc_state_endpoint_vals[] = {
4704         { 0,            "Consumer end of pipe"},
4705         { 1,            "Server end of pipe"},
4706         {0,     NULL}
4707 };
4708 static const value_string ipc_state_pipe_type_vals[] = {
4709         { 0,            "Byte stream pipe"},
4710         { 1,            "Message pipe"},
4711         {0,     NULL}
4712 };
4713 static const value_string ipc_state_read_mode_vals[] = {
4714         { 0,            "Read pipe as a byte stream"},
4715         { 1,            "Read messages from pipe"},
4716         {0,     NULL}
4717 };
4718
4719 int
4720 dissect_ipc_state(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
4721     int offset, gboolean setstate)
4722 {
4723         guint16 mask;
4724         proto_item *item = NULL;
4725         proto_tree *tree = NULL;
4726
4727         mask = tvb_get_letohs(tvb, offset);
4728
4729         if(parent_tree){
4730                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4731                         "IPC State: 0x%04x", mask);
4732                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
4733         }
4734
4735         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
4736                 tvb, offset, 2, mask);
4737         if (!setstate) {
4738                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
4739                         tvb, offset, 2, mask);
4740                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
4741                         tvb, offset, 2, mask);
4742         }
4743         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
4744                 tvb, offset, 2, mask);
4745         if (!setstate) {
4746                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
4747                         tvb, offset, 2, mask);
4748         }
4749
4750         offset += 2;
4751
4752         return offset;
4753 }
4754
4755 static int
4756 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4757 {
4758         guint8  wc, cmd=0xff;
4759         guint16 andxoffset=0, bc;
4760         guint16 fid;
4761
4762         WORD_COUNT;
4763
4764         /* next smb command */
4765         cmd = tvb_get_guint8(tvb, offset);
4766         if(cmd!=0xff){
4767                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4768         } else {
4769                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4770         }
4771         offset += 1;
4772
4773         /* reserved byte */
4774         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4775         offset += 1;
4776
4777         /* andxoffset */
4778         andxoffset = tvb_get_letohs(tvb, offset);
4779         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4780         offset += 2;
4781
4782         /* fid */
4783         fid = tvb_get_letohs(tvb, offset);
4784         add_fid(tvb, pinfo, tree, offset, 2, fid);
4785         offset += 2;
4786
4787         /* File Attributes */
4788         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
4789
4790         /* last write time */
4791         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
4792         
4793         /* File Size */
4794         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4795         offset += 4;
4796
4797         /* granted access */
4798         offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
4799
4800         /* File Type */
4801         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
4802         offset += 2;
4803
4804         /* IPC State */
4805         offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
4806
4807         /* open_action */
4808         offset = dissect_open_action(tvb, pinfo, tree, offset);
4809
4810         /* server fid */
4811         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
4812         offset += 4;
4813
4814         /* 2 reserved bytes */
4815         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4816         offset += 2;
4817
4818         BYTE_COUNT;
4819
4820         END_OF_SMB
4821
4822         /* call AndXCommand (if there are any) */
4823         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4824
4825         return offset;
4826 }
4827
4828 static int
4829 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4830 {
4831         guint8  wc, cmd=0xff;
4832         guint16 andxoffset=0, bc, maxcnt = 0;
4833         guint32 ofs = 0;
4834         smb_info_t *si;
4835         unsigned int fid;
4836
4837         WORD_COUNT;
4838
4839         /* next smb command */
4840         cmd = tvb_get_guint8(tvb, offset);
4841         if(cmd!=0xff){
4842                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4843         } else {
4844                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4845         }
4846         offset += 1;
4847
4848         /* reserved byte */
4849         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4850         offset += 1;
4851
4852         /* andxoffset */
4853         andxoffset = tvb_get_letohs(tvb, offset);
4854         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4855         offset += 2;
4856
4857         /* fid */
4858         fid = tvb_get_letohs(tvb, offset);
4859         add_fid(tvb, pinfo, tree, offset, 2, fid);
4860         offset += 2;
4861         if (!pinfo->fd->flags.visited) {
4862                 /* remember the FID for the processing of the response */
4863                 si = (smb_info_t *)pinfo->private_data;
4864                 si->sip->extra_info=(void *)fid;
4865         }
4866
4867         /* offset */
4868         ofs = tvb_get_letohl(tvb, offset);
4869         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4870         offset += 4;
4871
4872         /* max count */
4873         maxcnt = tvb_get_letohs(tvb, offset);
4874         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4875         offset += 2;
4876
4877         if (check_col(pinfo->cinfo, COL_INFO))
4878                 col_append_fstr(pinfo->cinfo, COL_INFO, 
4879                                 ", %d byte%s at offset %d", maxcnt, 
4880                                 (maxcnt == 1) ? "" : "s", ofs);
4881
4882         /* min count */
4883         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4884         offset += 2;
4885
4886         /* XXX - max count high */
4887         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4888         offset += 4;
4889
4890         /* remaining */
4891         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4892         offset += 2;
4893
4894         if(wc==12){
4895                 /* high offset */
4896                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
4897                 offset += 4;
4898         }
4899
4900         BYTE_COUNT;
4901
4902         END_OF_SMB
4903
4904         /* call AndXCommand (if there are any) */
4905         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4906
4907         return offset;
4908 }
4909
4910 static int
4911 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4912 {
4913         guint8  wc, cmd=0xff;
4914         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
4915         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4916         int fid=0;
4917
4918         WORD_COUNT;
4919
4920         /* next smb command */
4921         cmd = tvb_get_guint8(tvb, offset);
4922         if(cmd!=0xff){
4923                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4924         } else {
4925                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4926         }
4927         offset += 1;
4928  
4929         /* reserved byte */
4930         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4931         offset += 1;
4932
4933         /* andxoffset */
4934         andxoffset = tvb_get_letohs(tvb, offset);
4935         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4936         offset += 2;
4937
4938         /* If we have seen the request, then print which FID this refers to */
4939         /* first check if we have seen the request */
4940         if(si->sip != NULL && si->sip->frame_req>0){
4941                 fid=(int)si->sip->extra_info;
4942                 add_fid(tvb, pinfo, tree, 0, 0, fid);
4943         }
4944
4945         /* remaining */
4946         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4947         offset += 2;
4948
4949         /* data compaction mode */
4950         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4951         offset += 2;
4952
4953         /* 2 reserved bytes */
4954         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4955         offset += 2;
4956
4957         /* data len */
4958         datalen = tvb_get_letohs(tvb, offset);
4959         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4960         offset += 2;
4961
4962         if (check_col(pinfo->cinfo, COL_INFO))
4963                 col_append_fstr(pinfo->cinfo, COL_INFO, 
4964                                 ", %d byte%s", datalen, 
4965                                 (datalen == 1) ? "" : "s");
4966
4967         /* data offset */
4968         dataoffset=tvb_get_letohs(tvb, offset);
4969         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
4970         offset += 2;
4971
4972         /* 10 reserved bytes */
4973         /* XXX - first 2 bytes are data length high, not reserved */
4974         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
4975         offset += 10;
4976
4977         BYTE_COUNT;
4978
4979         /* is this part of DCERPC over SMB reassembly?*/
4980         if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited
4981             && (bc<=tvb_length_remaining(tvb, offset)) ){
4982                 gpointer hash_value;
4983                 if (si->sip != NULL && (hash_value = g_hash_table_lookup(
4984                                                 si->ct->dcerpc_fid_to_frame,
4985                                                 si->sip->extra_info)) != NULL) {
4986                         fragment_data *fd_head;
4987                         guint32 frame = GPOINTER_TO_UINT(hash_value);
4988
4989                         /* first fragment is always from a SMB Trans command and
4990                            offset 0 of the following read/write SMB commands start
4991                            BEYOND the first Trans SMB payload. Look for offset
4992                            in first read fragment */
4993                         fd_head=fragment_get(pinfo, frame, dcerpc_fragment_table);
4994                         if(fd_head){
4995                                 /* skip to last fragment  and add this data there*/
4996                                 while(fd_head->next){
4997                                         fd_head=fd_head->next;
4998                                 }
4999                                 /* if dataoffset was not specified in the SMB command
5000                                    then we try to guess it as good as we can
5001                                 */
5002                                 if(dataoffset==0){
5003                                         dataoffset=offset+bc-datalen;
5004                                 }
5005                                 fd_head=fragment_add(tvb, dataoffset, pinfo,
5006                                         frame, dcerpc_fragment_table,
5007                                         fd_head->offset+fd_head->len, 
5008                                         datalen, TRUE);
5009                                 /* we completed reassembly, abort searching for more 
5010                                    fragments*/
5011                                 if(fd_head){
5012                                         g_hash_table_remove(si->ct->dcerpc_fid_to_frame,
5013                                                 si->sip->extra_info);   
5014                                 }
5015                         }
5016                 }
5017         }
5018
5019         /* another way to transport DCERPC over SMB is to skip Transaction completely and just
5020            read write */
5021         if(bc){
5022                 if(si->sip != NULL && si->sip->flags&SMB_SIF_TID_IS_IPC){
5023                         /* dcerpc call */
5024                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
5025                             top_tree, offset, bc, datalen, fid);
5026                 } else {
5027                         /* ordinary file data, or we didn't see the request,
5028                            so we don't know whether this is a DCERPC call
5029                            or not */
5030                         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
5031                 }
5032                 bc = 0;
5033         }
5034
5035         END_OF_SMB
5036
5037         /* call AndXCommand (if there are any) */
5038         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5039
5040         return offset;
5041 }
5042
5043 static int
5044 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5045 {
5046         guint32 ofs=0;
5047         guint8  wc, cmd=0xff;
5048         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
5049         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5050         unsigned int fid=0;
5051
5052         WORD_COUNT;
5053
5054         /* next smb command */
5055         cmd = tvb_get_guint8(tvb, offset);
5056         if(cmd!=0xff){
5057                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5058         } else {
5059                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5060         }
5061         offset += 1;
5062
5063         /* reserved byte */
5064         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5065         offset += 1;
5066
5067         /* andxoffset */
5068         andxoffset = tvb_get_letohs(tvb, offset);
5069         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5070         offset += 2;
5071
5072         /* fid */
5073         fid = tvb_get_letohs(tvb, offset);
5074         add_fid(tvb, pinfo, tree, offset, 2, fid);
5075         offset += 2;
5076         if (!pinfo->fd->flags.visited) {
5077                 /* remember the FID for the processing of the response */
5078                 si->sip->extra_info=(void *)fid;
5079         }
5080
5081         /* offset */
5082         ofs = tvb_get_letohl(tvb, offset);
5083         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5084         offset += 4;
5085
5086         /* reserved */
5087         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5088         offset += 4;
5089
5090         /* mode */
5091         offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x000f);
5092
5093         /* remaining */
5094         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5095         offset += 2;
5096
5097         /* XXX - data length high */
5098         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5099         offset += 2;
5100
5101         /* data len */
5102         datalen = tvb_get_letohs(tvb, offset);
5103         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
5104         offset += 2;
5105
5106         /* data offset */
5107         dataoffset=tvb_get_letohs(tvb, offset);
5108         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5109         offset += 2;
5110
5111         /* FIXME: add byte/offset to COL_INFO */
5112
5113         if(wc==14){
5114                 /* high offset */
5115                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5116                 offset += 4;
5117         }
5118
5119         BYTE_COUNT;
5120
5121         /* is this part of DCERPC over SMB reassembly?*/
5122         if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited && (bc<=tvb_length_remaining(tvb, offset)) ){
5123                 gpointer hash_value;
5124                 hash_value = g_hash_table_lookup(si->ct->dcerpc_fid_to_frame,
5125                         si->sip->extra_info);
5126                 if(hash_value){
5127                         fragment_data *fd_head;
5128                         guint32 frame = GPOINTER_TO_UINT(hash_value);
5129
5130                         /* first fragment is always from a SMB Trans command and
5131                            offset 0 of the following read/write SMB commands start
5132                            BEYOND the first Trans SMB payload. Look for offset
5133                            in first read fragment */
5134                         fd_head=fragment_get(pinfo, frame, dcerpc_fragment_table);
5135                         if(fd_head){
5136                                 /* skip to last fragment  and add this data there*/
5137                                 while(fd_head->next){
5138                                         fd_head=fd_head->next;
5139                                 }
5140                                 /* if dataoffset was not specified in the SMB command
5141                                    then we try to guess it as good as we can
5142                                 */
5143                                 if(dataoffset==0){
5144                                         dataoffset=offset+bc-datalen;
5145                                 }
5146                                 fd_head=fragment_add(tvb, dataoffset, pinfo,
5147                                         frame, dcerpc_fragment_table,
5148                                         fd_head->offset+fd_head->len, 
5149                                         datalen, TRUE);
5150                                 /* we completed reassembly, abort searching for more 
5151                                    fragments*/
5152                                 if(fd_head){
5153                                         g_hash_table_remove(si->ct->dcerpc_fid_to_frame,
5154                                                 si->sip->extra_info);   
5155                                 }
5156                         }
5157                 }
5158         }
5159
5160         /* file data */
5161         if (bc != 0) {
5162                 if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
5163                         /* dcerpc call */
5164                         offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
5165                             top_tree, offset, bc, datalen, fid);
5166                 } else {
5167                         /* ordinary file data */
5168                         offset = dissect_file_data(tvb, pinfo, tree, offset,
5169                             bc, datalen);
5170                 }
5171                 bc = 0;
5172         }
5173
5174         END_OF_SMB
5175
5176         /* call AndXCommand (if there are any) */
5177         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5178
5179         return offset;
5180 }
5181
5182 static int
5183 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5184 {
5185         guint8  wc, cmd=0xff;
5186         guint16 andxoffset=0, bc;
5187         smb_info_t *si;
5188
5189         WORD_COUNT;
5190
5191         /* next smb command */
5192         cmd = tvb_get_guint8(tvb, offset);
5193         if(cmd!=0xff){
5194                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5195         } else {
5196                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5197         }
5198         offset += 1;
5199  
5200         /* reserved byte */
5201         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5202         offset += 1;
5203
5204         /* andxoffset */
5205         andxoffset = tvb_get_letohs(tvb, offset);
5206         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5207         offset += 2;
5208
5209         /* If we have seen the request, then print which FID this refers to */
5210         si = (smb_info_t *)pinfo->private_data;
5211         /* first check if we have seen the request */
5212         if(si->sip != NULL && si->sip->frame_req>0){
5213                 add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
5214         }
5215
5216         /* write count */
5217         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
5218         offset += 2;
5219
5220         /* remaining */
5221         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5222         offset += 2;
5223
5224         /* 4 reserved bytes */
5225         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5226         offset += 4;
5227
5228         BYTE_COUNT;
5229
5230         END_OF_SMB
5231
5232         /* call AndXCommand (if there are any) */
5233         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5234
5235         return offset;
5236 }
5237
5238
5239 static const true_false_string tfs_setup_action_guest = {
5240         "Logged in as GUEST",
5241         "Not logged in as GUEST"
5242 };
5243 static int
5244 dissect_setup_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5245 {
5246         guint16 mask;
5247         proto_item *item = NULL;
5248         proto_tree *tree = NULL;
5249
5250         mask = tvb_get_letohs(tvb, offset);
5251
5252         if(parent_tree){
5253                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5254                         "Action: 0x%04x", mask);
5255                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
5256         }
5257
5258         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
5259                 tvb, offset, 2, mask);
5260
5261         offset += 2;
5262
5263         return offset;
5264 }
5265  
5266
5267 static int
5268 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5269 {
5270         guint8  wc, cmd=0xff;
5271         guint16 bc;
5272         guint16 andxoffset=0;
5273         int an_len;
5274         const char *an;
5275         int dn_len;
5276         const char *dn;
5277         guint16 pwlen=0;
5278         guint16 sbloblen=0;
5279         guint16 apwlen=0, upwlen=0;
5280
5281         WORD_COUNT;
5282
5283         /* next smb command */
5284         cmd = tvb_get_guint8(tvb, offset);
5285         if(cmd!=0xff){
5286                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5287         } else {
5288                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5289         }
5290         offset += 1;
5291
5292         /* reserved byte */
5293         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5294         offset += 1;
5295
5296         /* andxoffset */
5297         andxoffset = tvb_get_letohs(tvb, offset);
5298         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5299         offset += 2;
5300
5301         /* Maximum Buffer Size */
5302         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
5303         offset += 2;
5304
5305         /* Maximum Multiplex Count */
5306         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
5307         offset += 2;
5308
5309         /* VC Number */
5310         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
5311         offset += 2;
5312
5313         /* session key */
5314         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
5315         offset += 4;
5316
5317         switch (wc) {
5318         case 10:
5319                 /* password length, ASCII*/
5320                 pwlen = tvb_get_letohs(tvb, offset);
5321                 proto_tree_add_uint(tree, hf_smb_password_len,
5322                         tvb, offset, 2, pwlen);
5323                 offset += 2;
5324
5325                 /* 4 reserved bytes */
5326                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5327                 offset += 4;
5328
5329                 break;
5330
5331         case 12:
5332                 /* security blob length */
5333                 sbloblen = tvb_get_letohs(tvb, offset);
5334                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5335                 offset += 2;
5336
5337                 /* 4 reserved bytes */
5338                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5339                 offset += 4;
5340
5341                 /* capabilities */
5342                 dissect_negprot_capabilities(tvb, pinfo, tree, offset);
5343                 offset += 4;
5344
5345                 break;
5346
5347         case 13:
5348                 /* password length, ANSI*/
5349                 apwlen = tvb_get_letohs(tvb, offset);
5350                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
5351                         tvb, offset, 2, apwlen);
5352                 offset += 2;
5353
5354                 /* password length, Unicode*/
5355                 upwlen = tvb_get_letohs(tvb, offset);
5356                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
5357                         tvb, offset, 2, upwlen);
5358                 offset += 2;
5359
5360                 /* 4 reserved bytes */
5361                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5362                 offset += 4;
5363
5364                 /* capabilities */
5365                 dissect_negprot_capabilities(tvb, pinfo, tree, offset);
5366                 offset += 4;
5367
5368                 break;
5369         }
5370
5371         BYTE_COUNT;
5372
5373         if (wc==12) {
5374                 /* security blob */
5375                 /* XXX - is this ASN.1-encoded?  Is it a Kerberos
5376                    data structure, at least in NT 5.0-and-later
5377                    server replies? */
5378                 if(sbloblen){
5379                         CHECK_BYTE_COUNT(sbloblen);
5380                         proto_tree_add_item(tree, hf_smb_security_blob,
5381                                 tvb, offset, sbloblen, TRUE);
5382                         COUNT_BYTES(sbloblen);
5383                 }
5384
5385                 /* OS */
5386                 an = get_unicode_or_ascii_string(tvb, &offset,
5387                         pinfo, &an_len, FALSE, FALSE, &bc);
5388                 if (an == NULL)
5389                         goto endofcommand;
5390                 proto_tree_add_string(tree, hf_smb_os, tvb,
5391                         offset, an_len, an);
5392                 COUNT_BYTES(an_len);
5393
5394                 /* LANMAN */
5395                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5396                  * padding/null string/whatever in front of this. W2K doesn't
5397                  * appear to. I suspect that's a bug that got fixed; I also
5398                  * suspect that, in practice, nobody ever looks at that field
5399                  * because the bug didn't appear to get fixed until NT 5.0....
5400                  */
5401                 an = get_unicode_or_ascii_string(tvb, &offset,
5402                         pinfo, &an_len, FALSE, FALSE, &bc);
5403                 if (an == NULL)
5404                         goto endofcommand;
5405                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5406                         offset, an_len, an);
5407                 COUNT_BYTES(an_len);
5408
5409                 /* Primary domain */
5410                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5411                  * byte in front of this, at least if all the strings are
5412                  * ASCII and the account name is empty. Another bug?
5413                  */
5414                 dn = get_unicode_or_ascii_string(tvb, &offset,
5415                         pinfo, &dn_len, FALSE, FALSE, &bc);
5416                 if (dn == NULL)
5417                         goto endofcommand;
5418                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5419                         offset, dn_len, dn);
5420                 COUNT_BYTES(dn_len);
5421         } else {
5422                 switch (wc) {
5423
5424                 case 10:
5425                         if(pwlen){
5426                                 /* password, ASCII */
5427                                 CHECK_BYTE_COUNT(pwlen);
5428                                 proto_tree_add_item(tree, hf_smb_password, 
5429                                         tvb, offset, pwlen, TRUE);
5430                                 COUNT_BYTES(pwlen);
5431                         }
5432
5433                         break;
5434
5435                 case 13:
5436                         if(apwlen){
5437                                 /* password, ANSI */
5438                                 CHECK_BYTE_COUNT(apwlen);
5439                                 proto_tree_add_item(tree, hf_smb_ansi_password, 
5440                                         tvb, offset, apwlen, TRUE);
5441                                 COUNT_BYTES(apwlen);
5442                         }
5443
5444                         if(upwlen){
5445                                 /* password, Unicode */
5446                                 CHECK_BYTE_COUNT(upwlen);
5447                                 proto_tree_add_item(tree, hf_smb_unicode_password, 
5448                                         tvb, offset, upwlen, TRUE);
5449                                 COUNT_BYTES(upwlen);
5450                         }
5451
5452                         break;
5453                 }
5454
5455                 /* Account Name */
5456                 an = get_unicode_or_ascii_string(tvb, &offset,
5457                         pinfo, &an_len, FALSE, FALSE, &bc);
5458                 if (an == NULL)
5459                         goto endofcommand;
5460                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
5461                         an);
5462                 COUNT_BYTES(an_len);
5463
5464                 /* Primary domain */
5465                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5466                  * byte in front of this, at least if all the strings are
5467                  * ASCII and the account name is empty. Another bug?
5468                  */
5469                 dn = get_unicode_or_ascii_string(tvb, &offset,
5470                         pinfo, &dn_len, FALSE, FALSE, &bc);
5471                 if (dn == NULL)
5472                         goto endofcommand;
5473                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5474                         offset, dn_len, dn);
5475                 COUNT_BYTES(dn_len);
5476
5477                 if (check_col(pinfo->cinfo, COL_INFO)) {
5478                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
5479
5480                         if (!dn[0] && !an[0])
5481                                 col_append_fstr(pinfo->cinfo, COL_INFO, 
5482                                                 "anonymous");
5483                         else
5484                                 col_append_fstr(pinfo->cinfo, COL_INFO, 
5485                                                 "%s\\%s", dn,an);
5486                 }
5487
5488                 /* OS */
5489                 an = get_unicode_or_ascii_string(tvb, &offset,
5490                         pinfo, &an_len, FALSE, FALSE, &bc);
5491                 if (an == NULL)
5492                         goto endofcommand;
5493                 proto_tree_add_string(tree, hf_smb_os, tvb,
5494                         offset, an_len, an);
5495                 COUNT_BYTES(an_len);
5496
5497                 /* LANMAN */
5498                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5499                  * padding/null string/whatever in front of this. W2K doesn't
5500                  * appear to. I suspect that's a bug that got fixed; I also
5501                  * suspect that, in practice, nobody ever looks at that field
5502                  * because the bug didn't appear to get fixed until NT 5.0....
5503                  */
5504                 an = get_unicode_or_ascii_string(tvb, &offset,
5505                         pinfo, &an_len, FALSE, FALSE, &bc);
5506                 if (an == NULL)
5507                         goto endofcommand;
5508                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5509                         offset, an_len, an);
5510                 COUNT_BYTES(an_len);
5511         }
5512
5513         END_OF_SMB
5514
5515         /* call AndXCommand (if there are any) */
5516         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5517
5518         return offset;
5519 }
5520
5521 static int
5522 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5523 {
5524         guint8  wc, cmd=0xff;
5525         guint16 andxoffset=0, bc;
5526         guint16 sbloblen=0;
5527         int an_len;
5528         const char *an;
5529
5530         WORD_COUNT;
5531
5532         /* next smb command */
5533         cmd = tvb_get_guint8(tvb, offset);
5534         if(cmd!=0xff){
5535                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5536         } else {
5537                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5538         }
5539         offset += 1;
5540
5541         /* reserved byte */
5542         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5543         offset += 1;
5544
5545         /* andxoffset */
5546         andxoffset = tvb_get_letohs(tvb, offset);
5547         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5548         offset += 2;
5549
5550         /* flags */
5551         offset = dissect_setup_action(tvb, pinfo, tree, offset);
5552
5553         if(wc==4){
5554                 /* security blob length */
5555                 sbloblen = tvb_get_letohs(tvb, offset);
5556                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5557                 offset += 2;
5558         }
5559
5560         BYTE_COUNT;
5561
5562         if(wc==4) {
5563                 /* security blob */
5564                 /* XXX - is this ASN.1-encoded?  Is it a Kerberos
5565                    data structure, at least in NT 5.0-and-later
5566                    server replies? */
5567                 if(sbloblen){
5568                         CHECK_BYTE_COUNT(sbloblen);
5569                         proto_tree_add_item(tree, hf_smb_security_blob,
5570                                 tvb, offset, sbloblen, TRUE);
5571                         COUNT_BYTES(sbloblen);
5572                 }
5573         }
5574
5575         /* OS */
5576         an = get_unicode_or_ascii_string(tvb, &offset,
5577                 pinfo, &an_len, FALSE, FALSE, &bc);
5578         if (an == NULL)
5579                 goto endofcommand;
5580         proto_tree_add_string(tree, hf_smb_os, tvb,
5581                 offset, an_len, an);
5582         COUNT_BYTES(an_len);
5583
5584         /* LANMAN */
5585         an = get_unicode_or_ascii_string(tvb, &offset,
5586                 pinfo, &an_len, FALSE, FALSE, &bc);
5587         if (an == NULL)
5588                 goto endofcommand;
5589         proto_tree_add_string(tree, hf_smb_lanman, tvb,
5590                 offset, an_len, an);
5591         COUNT_BYTES(an_len);
5592
5593         if(wc==3) {
5594                 /* Primary domain */
5595                 an = get_unicode_or_ascii_string(tvb, &offset,
5596                         pinfo, &an_len, FALSE, FALSE, &bc);
5597                 if (an == NULL)
5598                         goto endofcommand;
5599                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5600                         offset, an_len, an);
5601                 COUNT_BYTES(an_len);
5602         }
5603
5604         END_OF_SMB
5605
5606         /* call AndXCommand (if there are any) */
5607         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5608
5609         return offset;
5610 }
5611
5612  
5613 static int
5614 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5615 {
5616         guint8  wc, cmd=0xff;
5617         guint16 andxoffset=0;
5618         guint16 bc;
5619
5620         WORD_COUNT;
5621
5622         /* next smb command */
5623         cmd = tvb_get_guint8(tvb, offset);
5624         if(cmd!=0xff){
5625                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5626         } else {
5627                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5628         }
5629         offset += 1;
5630
5631         /* reserved byte */
5632         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5633         offset += 1;
5634
5635         /* andxoffset */
5636         andxoffset = tvb_get_letohs(tvb, offset);
5637         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5638         offset += 2;
5639
5640         BYTE_COUNT;
5641
5642         END_OF_SMB
5643
5644         /* call AndXCommand (if there are any) */
5645         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5646
5647         return offset;
5648 }
5649
5650  
5651 static const true_false_string tfs_connect_support_search = {
5652         "Exclusive search bits supported",
5653         "Exclusive search bits not supported"
5654 };
5655 static const true_false_string tfs_connect_support_in_dfs = {
5656         "Share is in Dfs",
5657         "Share isn't in Dfs"
5658 };
5659
5660 static int
5661 dissect_connect_support_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5662 {
5663         guint16 mask;
5664         proto_item *item = NULL;
5665         proto_tree *tree = NULL;
5666
5667         mask = tvb_get_letohs(tvb, offset);
5668
5669         if(parent_tree){
5670                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5671                         "Optional Support: 0x%04x", mask);
5672                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
5673         }
5674
5675         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
5676                 tvb, offset, 2, mask);
5677         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
5678                 tvb, offset, 2, mask);
5679
5680         offset += 2;
5681
5682         return offset;
5683 }
5684
5685 static const true_false_string tfs_disconnect_tid = {
5686         "DISCONNECT TID",
5687         "Do NOT disconnect TID"
5688 };
5689
5690 static int
5691 dissect_connect_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5692 {
5693         guint16 mask;
5694         proto_item *item = NULL;
5695         proto_tree *tree = NULL;
5696
5697         mask = tvb_get_letohs(tvb, offset);
5698
5699         if(parent_tree){
5700                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5701                         "Flags: 0x%04x", mask);
5702                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
5703         }
5704
5705         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
5706                 tvb, offset, 2, mask);
5707
5708         offset += 2;
5709
5710         return offset;
5711 }
5712
5713 static int
5714 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5715 {
5716         guint8  wc, cmd=0xff;
5717         guint16 bc;
5718         guint16 andxoffset=0, pwlen=0;
5719         int an_len;
5720         const char *an;
5721
5722         WORD_COUNT;
5723
5724         /* next smb command */
5725         cmd = tvb_get_guint8(tvb, offset);
5726         if(cmd!=0xff){
5727                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5728         } else {
5729                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
5730         }
5731         offset += 1;
5732
5733         /* reserved byte */
5734         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5735         offset += 1;
5736
5737         /* andxoffset */
5738         andxoffset = tvb_get_letohs(tvb, offset);
5739         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5740         offset += 2;
5741
5742         /* flags */
5743         offset = dissect_connect_flags(tvb, pinfo, tree, offset);
5744
5745         /* password length*/
5746         pwlen = tvb_get_letohs(tvb, offset);
5747         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
5748         offset += 2;
5749
5750         BYTE_COUNT;
5751
5752         /* password */
5753         CHECK_BYTE_COUNT(pwlen);
5754         proto_tree_add_item(tree, hf_smb_password, 
5755                 tvb, offset, pwlen, TRUE);
5756         COUNT_BYTES(pwlen);
5757
5758         /* Path */
5759         an = get_unicode_or_ascii_string(tvb, &offset,
5760                 pinfo, &an_len, FALSE, FALSE, &bc);
5761         if (an == NULL)
5762                 goto endofcommand;
5763         proto_tree_add_string(tree, hf_smb_path, tvb,
5764                 offset, an_len, an);
5765         COUNT_BYTES(an_len);
5766
5767         if (check_col(pinfo->cinfo, COL_INFO)) {
5768                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
5769         }
5770
5771         /*
5772          * NOTE: the Service string is always ASCII, even if the
5773          * "strings are Unicode" bit is set in the flags2 field
5774          * of the SMB.
5775          */
5776
5777         /* Service */
5778         /* XXX - what if this runs past bc? */
5779         an_len = tvb_strsize(tvb, offset);
5780         CHECK_BYTE_COUNT(an_len);
5781         an = tvb_get_ptr(tvb, offset, an_len);
5782         proto_tree_add_string(tree, hf_smb_service, tvb,
5783                 offset, an_len, an);
5784         COUNT_BYTES(an_len);
5785
5786         END_OF_SMB
5787
5788         /* call AndXCommand (if there are any) */
5789         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5790
5791         return offset;
5792 }
5793
5794
5795 static int
5796 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5797 {
5798         guint8  wc, wleft, cmd=0xff;
5799         guint16 andxoffset=0;
5800         guint16 bc;
5801         int an_len;
5802         const char *an;
5803
5804         WORD_COUNT;
5805
5806         wleft = wc;     /* this is at least 1 */
5807
5808         /* next smb command */
5809         cmd = tvb_get_guint8(tvb, offset);
5810         if(cmd!=0xff){
5811                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5812         } else {
5813                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
5814         }
5815         offset += 1;
5816
5817         /* reserved byte */
5818         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5819         offset += 1;
5820
5821         wleft--;
5822         if (wleft == 0)
5823                 goto bytecount;
5824
5825         /* andxoffset */
5826         andxoffset = tvb_get_letohs(tvb, offset);
5827         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5828         offset += 2;
5829         wleft--;
5830         if (wleft == 0)
5831                 goto bytecount;
5832
5833         /* flags */
5834         offset = dissect_connect_support_bits(tvb, pinfo, tree, offset);
5835         wleft--;
5836
5837         /* XXX - I've seen captures where this is 7, but I have no
5838            idea how to dissect it.  I'm guessing the third word
5839            contains connect support bits, which looks plausible
5840            from the values I've seen. */
5841
5842         while (wleft != 0) {
5843                 proto_tree_add_text(tree, tvb, offset, 2,
5844                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
5845                 offset += 2;
5846                 wleft--;
5847         }
5848
5849         BYTE_COUNT;
5850
5851         /*
5852          * NOTE: even though the SNIA CIFS spec doesn't say there's
5853          * a "Service" string if there's a word count of 2, the
5854          * document at
5855          *
5856          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
5857          *
5858          * (it's in an ugly format - text intended to be sent to a
5859          * printer, with backspaces and overstrikes used for boldfacing
5860          * and underlining; UNIX "col -b" can be used to strip the
5861          * overstrikes out) says there's a "Service" string there, and
5862          * some network traffic has it.
5863          */
5864
5865         /*
5866          * NOTE: the Service string is always ASCII, even if the
5867          * "strings are Unicode" bit is set in the flags2 field
5868          * of the SMB.
5869          */
5870
5871         /* Service */
5872         /* XXX - what if this runs past bc? */
5873         an_len = tvb_strsize(tvb, offset);
5874         CHECK_BYTE_COUNT(an_len);
5875         an = tvb_get_ptr(tvb, offset, an_len);
5876         proto_tree_add_string(tree, hf_smb_service, tvb,
5877                 offset, an_len, an);
5878         COUNT_BYTES(an_len);
5879
5880         /* Now when we know the service type, store it so that we know it for later commands down
5881            this tree */
5882         if(!pinfo->fd->flags.visited){
5883                 smb_info_t *si = (smb_info_t *)pinfo->private_data;
5884                 /* Remove any previous entry for this TID */
5885                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
5886                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
5887                 }
5888                 if(strcmp(an,"IPC") == 0){
5889                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
5890                 } else {
5891                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
5892                 }
5893         }
5894
5895
5896         if(wc==3){
5897                 if (bc != 0) {
5898                         /*
5899                          * Sometimes this isn't present.
5900                          */
5901
5902                         /* Native FS */
5903                         an = get_unicode_or_ascii_string(tvb, &offset,
5904                                 pinfo, &an_len, /*TRUE*/FALSE, FALSE, &bc);
5905                         if (an == NULL)
5906                                 goto endofcommand;
5907                         proto_tree_add_string(tree, hf_smb_fs, tvb,
5908                                 offset, an_len, an);
5909                         COUNT_BYTES(an_len);
5910                 }
5911         }
5912
5913         END_OF_SMB
5914
5915         /* call AndXCommand (if there are any) */
5916         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5917
5918         return offset;
5919 }
5920
5921
5922
5923 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5924    NT Transaction command  begins here
5925    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
5926 #define NT_TRANS_CREATE         1
5927 #define NT_TRANS_IOCTL          2
5928 #define NT_TRANS_SSD            3
5929 #define NT_TRANS_NOTIFY         4
5930 #define NT_TRANS_RENAME         5
5931 #define NT_TRANS_QSD            6
5932 #define NT_TRANS_GET_USER_QUOTA 7
5933 #define NT_TRANS_SET_USER_QUOTA 8
5934 static const value_string nt_cmd_vals[] = {
5935         {NT_TRANS_CREATE,               "NT CREATE"},
5936         {NT_TRANS_IOCTL,                "NT IOCTL"},
5937         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
5938         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
5939         {NT_TRANS_RENAME,               "NT RENAME"},
5940         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
5941         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
5942         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
5943         {0, NULL}
5944 };
5945
5946 static const value_string nt_ioctl_isfsctl_vals[] = {
5947         {0,     "Device IOCTL"},
5948         {1,     "FS control : FSCTL"},
5949         {0, NULL}
5950 };
5951
5952 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
5953 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
5954         "Apply the command to share root handle (MUST BE Dfs)",
5955         "Apply to this share",
5956 };
5957
5958 static const value_string nt_notify_action_vals[] = {
5959         {1,     "ADDED (object was added"},
5960         {2,     "REMOVED (object was removed)"},
5961         {3,     "MODIFIED (object was modified)"},
5962         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
5963         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
5964         {6,     "ADDED_STREAM (a stream was added)"},
5965         {7,     "REMOVED_STREAM (a stream was removed)"},
5966         {8,     "MODIFIED_STREAM (a stream was modified)"},
5967         {0, NULL}
5968 };
5969
5970 static const value_string watch_tree_vals[] = {
5971         {0,     "Current directory only"},
5972         {1,     "Subdirectories also"},
5973         {0, NULL}
5974 };
5975
5976 #define NT_NOTIFY_STREAM_WRITE  0x00000800
5977 #define NT_NOTIFY_STREAM_SIZE   0x00000400
5978 #define NT_NOTIFY_STREAM_NAME   0x00000200
5979 #define NT_NOTIFY_SECURITY      0x00000100
5980 #define NT_NOTIFY_EA            0x00000080
5981 #define NT_NOTIFY_CREATION      0x00000040
5982 #define NT_NOTIFY_LAST_ACCESS   0x00000020
5983 #define NT_NOTIFY_LAST_WRITE    0x00000010
5984 #define NT_NOTIFY_SIZE          0x00000008
5985 #define NT_NOTIFY_ATTRIBUTES    0x00000004
5986 #define NT_NOTIFY_DIR_NAME      0x00000002
5987 #define NT_NOTIFY_FILE_NAME     0x00000001
5988 static const true_false_string tfs_nt_notify_stream_write = {
5989         "Notify on changes to STREAM WRITE",
5990         "Do NOT notify on changes to stream write",
5991 };
5992 static const true_false_string tfs_nt_notify_stream_size = {
5993         "Notify on changes to STREAM SIZE",
5994         "Do NOT notify on changes to stream size",
5995 };
5996 static const true_false_string tfs_nt_notify_stream_name = {
5997         "Notify on changes to STREAM NAME",
5998         "Do NOT notify on changes to stream name",
5999 };
6000 static const true_false_string tfs_nt_notify_security = {
6001         "Notify on changes to SECURITY",
6002         "Do NOT notify on changes to security",
6003 };
6004 static const true_false_string tfs_nt_notify_ea = {
6005         "Notify on changes to EA",
6006         "Do NOT notify on changes to EA",
6007 };
6008 static const true_false_string tfs_nt_notify_creation = {
6009         "Notify on changes to CREATION TIME",
6010         "Do NOT notify on changes to creation time",
6011 };
6012 static const true_false_string tfs_nt_notify_last_access = {
6013         "Notify on changes to LAST ACCESS TIME",
6014         "Do NOT notify on changes to last access time",
6015 };
6016 static const true_false_string tfs_nt_notify_last_write = {
6017         "Notify on changes to LAST WRITE TIME",
6018         "Do NOT notify on changes to last write time",
6019 };
6020 static const true_false_string tfs_nt_notify_size = {
6021         "Notify on changes to SIZE",
6022         "Do NOT notify on changes to size",
6023 };
6024 static const true_false_string tfs_nt_notify_attributes = {
6025         "Notify on changes to ATTRIBUTES",
6026         "Do NOT notify on changes to attributes",
6027 };
6028 static const true_false_string tfs_nt_notify_dir_name = {
6029         "Notify on changes to DIR NAME",
6030         "Do NOT notify on changes to dir name",
6031 };
6032 static const true_false_string tfs_nt_notify_file_name = {
6033         "Notify on changes to FILE NAME",
6034         "Do NOT notify on changes to file name",
6035 };
6036
6037 static const value_string create_disposition_vals[] = {
6038         {0,     "Supersede (supersede existing file (if it exists))"},
6039         {1,     "Open (if file exists open it, else fail)"},
6040         {2,     "Create (if file exists fail, else create it)"},
6041         {3,     "Open If (if file exists open it, else create it)"},
6042         {4,     "Overwrite (if file exists overwrite, else fail)"},
6043         {5,     "Overwrite If (if file exists overwrite, else create it)"},
6044         {0, NULL}
6045 };
6046
6047 static const value_string impersonation_level_vals[] = {
6048         {0,     "Anonymous"},
6049         {1,     "Identification"},
6050         {2,     "Impersonation"},
6051         {3,     "Delegation"},
6052         {0, NULL}
6053 };
6054
6055 static const true_false_string tfs_nt_security_flags_context_tracking = {
6056         "Security tracking mode is DYNAMIC",
6057         "Security tracking mode is STATIC",
6058 };
6059
6060 static const true_false_string tfs_nt_security_flags_effective_only = {
6061         "ONLY ENABLED aspects of the client's security context are available",
6062         "ALL aspects of the client's security context are available",
6063 };
6064
6065 static const true_false_string tfs_nt_create_bits_oplock = {
6066         "Requesting OPLOCK",
6067         "Does NOT request oplock"
6068 };
6069
6070 static const true_false_string tfs_nt_create_bits_boplock = {
6071         "Requesting BATCH OPLOCK",
6072         "Does NOT request batch oplock"
6073 };
6074
6075 /*
6076  * XXX - must be a directory, and can be a file, or can be a directory,
6077  * and must be a file?
6078  */
6079 static const true_false_string tfs_nt_create_bits_dir = {
6080         "Target of open MUST be a DIRECTORY",
6081         "Target of open can be a file"
6082 };
6083
6084 static const true_false_string tfs_nt_access_mask_generic_read = {
6085         "GENERIC READ is set",
6086         "Generic read is NOT set"
6087 };
6088 static const true_false_string tfs_nt_access_mask_generic_write = {
6089         "GENERIC WRITE is set",
6090         "Generic write is NOT set"
6091 };
6092 static const true_false_string tfs_nt_access_mask_generic_execute = {
6093         "GENERIC EXECUTE is set",
6094         "Generic execute is NOT set"
6095 };
6096 static const true_false_string tfs_nt_access_mask_generic_all = {
6097         "GENERIC ALL is set",
6098         "Generic all is NOT set"
6099 };
6100 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
6101         "MAXIMUM ALLOWED is set",
6102         "Maximum allowed is NOT set"
6103 };
6104 static const true_false_string tfs_nt_access_mask_system_security = {
6105         "SYSTEM SECURITY is set",
6106         "System security is NOT set"
6107 };
6108 static const true_false_string tfs_nt_access_mask_synchronize = {
6109         "Can wait on handle to SYNCHRONIZE on completion of I/O",
6110         "Can NOT wait on handle to synchronize on completion of I/O"
6111 };
6112 static const true_false_string tfs_nt_access_mask_write_owner = {
6113         "Can WRITE OWNER (take ownership)",
6114         "Can NOT write owner (take ownership)"
6115 };
6116 static const true_false_string tfs_nt_access_mask_write_dac = {
6117         "OWNER may WRITE the DAC",
6118         "Owner may NOT write to the DAC"
6119 };
6120 static const true_false_string tfs_nt_access_mask_read_control = {
6121         "READ ACCESS to owner, group and ACL of the SID",
6122         "Read access is NOT granted to owner, group and ACL of the SID"
6123 };
6124 static const true_false_string tfs_nt_access_mask_delete = {
6125         "DELETE access",
6126         "NO delete access"
6127 };
6128 static const true_false_string tfs_nt_access_mask_write_attributes = {
6129         "WRITE ATTRIBUTES access",
6130         "NO write attributes access"
6131 };
6132 static const true_false_string tfs_nt_access_mask_read_attributes = {
6133         "READ ATTRIBUTES access",
6134         "NO read attributes access"
6135 };
6136 static const true_false_string tfs_nt_access_mask_delete_child = {
6137         "DELETE CHILD access",
6138         "NO delete child access"
6139 };
6140 static const true_false_string tfs_nt_access_mask_execute = {
6141         "EXECUTE access",
6142         "NO execute access"
6143 };
6144 static const true_false_string tfs_nt_access_mask_write_ea = {
6145         "WRITE EXTENDED ATTRIBUTES access",
6146         "NO write extended attributes access"
6147 };
6148 static const true_false_string tfs_nt_access_mask_read_ea = {
6149         "READ EXTENDED ATTRIBUTES access",
6150         "NO read extended attributes access"
6151 };
6152 static const true_false_string tfs_nt_access_mask_append = {
6153         "APPEND access",
6154         "NO append access"
6155 };
6156 static const true_false_string tfs_nt_access_mask_write = {
6157         "WRITE access",
6158         "NO write access"
6159 };
6160 static const true_false_string tfs_nt_access_mask_read = {
6161         "READ access",
6162         "NO read access"
6163 };
6164
6165 static const true_false_string tfs_nt_share_access_delete = {
6166         "Object can be shared for DELETE",
6167         "Object can NOT be shared for delete"
6168 };
6169 static const true_false_string tfs_nt_share_access_write = {
6170         "Object can be shared for WRITE",
6171         "Object can NOT be shared for write"
6172 };
6173 static const true_false_string tfs_nt_share_access_read = {
6174         "Object can be shared for READ",
6175         "Object can NOT be shared for delete"
6176 };
6177
6178 static const value_string oplock_level_vals[] = {
6179         {0,     "No oplock granted"},
6180         {1,     "Exclusive oplock granted"},
6181         {2,     "Batch oplock granted"},
6182         {3,     "Level II oplock granted"},
6183         {0, NULL}
6184 };
6185
6186 static const value_string device_type_vals[] = {
6187         {0x00000001,    "Beep"},
6188         {0x00000002,    "CDROM"},
6189         {0x00000003,    "CDROM Filesystem"},
6190         {0x00000004,    "Controller"},
6191         {0x00000005,    "Datalink"},
6192         {0x00000006,    "Dfs"},
6193         {0x00000007,    "Disk"},
6194         {0x00000008,    "Disk Filesystem"},
6195         {0x00000009,    "Filesystem"},
6196         {0x0000000a,    "Inport Port"},
6197         {0x0000000b,    "Keyboard"},
6198         {0x0000000c,    "Mailslot"},
6199         {0x0000000d,    "MIDI-In"},
6200         {0x0000000e,    "MIDI-Out"},
6201         {0x0000000f,    "Mouse"},
6202         {0x00000010,    "Multi UNC Provider"},
6203         {0x00000011,    "Named Pipe"},
6204         {0x00000012,    "Network"},
6205         {0x00000013,    "Network Browser"},
6206         {0x00000014,    "Network Filesystem"},
6207         {0x00000015,    "NULL"},
6208         {0x00000016,    "Parallel Port"},
6209         {0x00000017,    "Physical card"},
6210         {0x00000018,    "Printer"},
6211         {0x00000019,    "Scanner"},
6212         {0x0000001a,    "Serial Mouse port"},
6213         {0x0000001b,    "Serial port"},
6214         {0x0000001c,    "Screen"},
6215         {0x0000001d,    "Sound"},
6216         {0x0000001e,    "Streams"},
6217         {0x0000001f,    "Tape"},
6218         {0x00000020,    "Tape Filesystem"},
6219         {0x00000021,    "Transport"},
6220         {0x00000022,    "Unknown"},
6221         {0x00000023,    "Video"},
6222         {0x00000024,    "Virtual Disk"},
6223         {0x00000025,    "WAVE-In"},
6224         {0x00000026,    "WAVE-Out"},
6225         {0x00000027,    "8042 Port"},
6226         {0x00000028,    "Network Redirector"},
6227         {0x00000029,    "Battery"},
6228         {0x0000002a,    "Bus Extender"},
6229         {0x0000002b,    "Modem"},
6230         {0x0000002c,    "VDM"},
6231         {0,     NULL}
6232 };
6233
6234 static const value_string is_directory_vals[] = {
6235         {0,     "This is NOT a directory"},
6236         {1,     "This is a DIRECTORY"},
6237         {0, NULL}
6238 };
6239
6240 typedef struct _nt_trans_data {
6241         int subcmd;
6242         guint32 sd_len;
6243         guint32 ea_len;
6244 } nt_trans_data;
6245
6246
6247
6248 static int
6249 dissect_nt_security_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6250 {
6251         guint8 mask;
6252         proto_item *item = NULL;
6253         proto_tree *tree = NULL;
6254
6255         mask = tvb_get_guint8(tvb, offset);
6256
6257         if(parent_tree){
6258                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6259                         "Security Flags: 0x%02x", mask);
6260                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
6261         }
6262
6263         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
6264                 tvb, offset, 1, mask);
6265         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
6266                 tvb, offset, 1, mask);
6267
6268         offset += 1;
6269
6270         return offset;
6271 }
6272
6273 static int
6274 dissect_nt_share_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6275 {
6276         guint32 mask;
6277         proto_item *item = NULL;
6278         proto_tree *tree = NULL;
6279
6280         mask = tvb_get_letohl(tvb, offset);
6281
6282         if(parent_tree){
6283                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6284                         "Share Access: 0x%08x", mask);
6285                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
6286         }
6287
6288         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
6289                 tvb, offset, 4, mask);
6290         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
6291                 tvb, offset, 4, mask);
6292         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
6293                 tvb, offset, 4, mask);
6294
6295         offset += 4;
6296
6297         return offset;
6298 }
6299
6300
6301 static int
6302 dissect_nt_access_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6303 {
6304         guint32 mask;
6305         proto_item *item = NULL;
6306         proto_tree *tree = NULL;
6307
6308         mask = tvb_get_letohl(tvb, offset);
6309
6310         if(parent_tree){
6311                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6312                         "Access Mask: 0x%08x", mask);
6313                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
6314         }
6315
6316         /*
6317          * Some of these bits come from 
6318          *
6319          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6320          *
6321          * and others come from the section on ZwOpenFile in "Windows(R)
6322          * NT(R)/2000 Native API Reference".
6323          */
6324         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
6325                 tvb, offset, 4, mask);
6326         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
6327                 tvb, offset, 4, mask);
6328         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
6329                 tvb, offset, 4, mask);
6330         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
6331                 tvb, offset, 4, mask);
6332         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
6333                 tvb, offset, 4, mask);
6334         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
6335                 tvb, offset, 4, mask);
6336         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
6337                 tvb, offset, 4, mask);
6338         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
6339                 tvb, offset, 4, mask);
6340         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
6341                 tvb, offset, 4, mask);
6342         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
6343                 tvb, offset, 4, mask);
6344         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
6345                 tvb, offset, 4, mask);
6346         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
6347                 tvb, offset, 4, mask);
6348         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
6349                 tvb, offset, 4, mask);
6350         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
6351                 tvb, offset, 4, mask);
6352         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
6353                 tvb, offset, 4, mask);
6354         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
6355                 tvb, offset, 4, mask);
6356         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
6357                 tvb, offset, 4, mask);
6358         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
6359                 tvb, offset, 4, mask);
6360         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
6361                 tvb, offset, 4, mask);
6362         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
6363                 tvb, offset, 4, mask);
6364
6365         offset += 4;
6366
6367         return offset;
6368 }
6369
6370 static int
6371 dissect_nt_create_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6372 {
6373         guint32 mask;
6374         proto_item *item = NULL;
6375         proto_tree *tree = NULL;
6376
6377         mask = tvb_get_letohl(tvb, offset);
6378
6379         if(parent_tree){
6380                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6381                         "Create Flags: 0x%08x", mask);
6382                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
6383         }
6384
6385         /*
6386          * XXX - it's 0x00000016 in at least one capture, but
6387          * Network Monitor doesn't say what the 0x00000010 bit is.
6388          * Does the Win32 API documentation, or NT Native API book,
6389          * suggest anything?
6390          */
6391         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
6392                 tvb, offset, 4, mask);
6393         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
6394                 tvb, offset, 4, mask);
6395         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
6396                 tvb, offset, 4, mask);
6397
6398         offset += 4;
6399
6400         return offset;
6401 }
6402
6403 /*
6404  * XXX - there are some more flags in the description of "ZwOpenFile()"
6405  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
6406  * the wire as well?  (The spec at
6407  *
6408  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6409  *
6410  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
6411  * via the SMB protocol.  The NT redirector should convert this option
6412  * to FILE_WRITE_THROUGH."
6413  *
6414  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
6415  * values one would infer from their position in the list of flags for
6416  * "ZwOpenFile()".  Most of the others probably have those values
6417  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
6418  * which might go over the wire (for the benefit of backup/restore software).
6419  */
6420 static const true_false_string tfs_nt_create_options_directory = {
6421         "File being created/opened must be a directory",
6422         "File being created/opened must not be a directory"
6423 };
6424 static const true_false_string tfs_nt_create_options_write_through = {
6425         "Writes should flush buffered data before completing",
6426         "Writes need not flush buffered data before completing"
6427 };
6428 static const true_false_string tfs_nt_create_options_sequential_only = {
6429         "The file will only be accessed sequentially",
6430         "The file might not only be accessed sequentially"
6431 };
6432 static const true_false_string tfs_nt_create_options_sync_io_alert = {
6433         "All operations SYNCHRONOUS, waits subject to termination from alert",
6434         "Operations NOT necessarily synchronous"
6435 };
6436 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
6437         "All operations SYNCHRONOUS, waits not subject to alert",
6438         "Operations NOT necessarily synchronous"
6439 };
6440 static const true_false_string tfs_nt_create_options_non_directory = {
6441         "File being created/opened must not be a directory",
6442         "File being created/opened must be a directory"
6443 };
6444 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
6445         "The client does not understand extended attributes",
6446         "The client understands extended attributes"
6447 };
6448 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
6449         "The client understands only 8.3 file names",
6450         "The client understands long file names"
6451 };
6452 static const true_false_string tfs_nt_create_options_random_access = {
6453         "The file will be accessed randomly",
6454         "The file will not be accessed randomly"
6455 };
6456 static const true_false_string tfs_nt_create_options_delete_on_close = {
6457         "The file should be deleted when it is closed",
6458         "The file should not be deleted when it is closed"
6459 };
6460
6461 static int
6462 dissect_nt_create_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6463 {
6464         guint32 mask;
6465         proto_item *item = NULL;
6466         proto_tree *tree = NULL;
6467
6468         mask = tvb_get_letohl(tvb, offset);
6469
6470         if(parent_tree){
6471                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6472                         "Create Options: 0x%08x", mask);
6473                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
6474         }
6475
6476         /*
6477          * From
6478          *
6479          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6480          */
6481         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
6482                 tvb, offset, 4, mask);
6483         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
6484                 tvb, offset, 4, mask);
6485         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
6486                 tvb, offset, 4, mask);
6487         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
6488                 tvb, offset, 4, mask);
6489         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
6490                 tvb, offset, 4, mask);
6491         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
6492                 tvb, offset, 4, mask);
6493         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
6494                 tvb, offset, 4, mask);
6495         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
6496                 tvb, offset, 4, mask);
6497         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
6498                 tvb, offset, 4, mask);
6499         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
6500                 tvb, offset, 4, mask);
6501
6502         offset += 4;
6503
6504         return offset;
6505 }
6506  
6507 static int
6508 dissect_nt_notify_completion_filter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6509 {
6510         guint32 mask;
6511         proto_item *item = NULL;
6512         proto_tree *tree = NULL;
6513
6514         mask = tvb_get_letohl(tvb, offset);
6515
6516         if(parent_tree){
6517                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6518                         "Completion Filter: 0x%08x", mask);
6519                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
6520         }
6521  
6522         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
6523                 tvb, offset, 4, mask);
6524         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
6525                 tvb, offset, 4, mask);
6526         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
6527                 tvb, offset, 4, mask);
6528         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
6529                 tvb, offset, 4, mask);
6530         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
6531                 tvb, offset, 4, mask);
6532         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
6533                 tvb, offset, 4, mask);
6534         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
6535                 tvb, offset, 4, mask);
6536         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
6537                 tvb, offset, 4, mask);
6538         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
6539                 tvb, offset, 4, mask);
6540         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
6541                 tvb, offset, 4, mask);
6542         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
6543                 tvb, offset, 4, mask);
6544         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
6545                 tvb, offset, 4, mask);
6546
6547         offset += 4;
6548         return offset;
6549 }
6550  
6551 static int
6552 dissect_nt_ioctl_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6553 {
6554         guint8 mask;
6555         proto_item *item = NULL;
6556         proto_tree *tree = NULL;
6557
6558         mask = tvb_get_guint8(tvb, offset);
6559
6560         if(parent_tree){
6561                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6562                         "Completion Filter: 0x%02x", mask);
6563                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
6564         }
6565
6566         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
6567                 tvb, offset, 1, mask);
6568
6569         offset += 1;
6570         return offset;
6571 }
6572
6573 /*
6574  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
6575  * Native API Reference".
6576  */
6577 static const true_false_string tfs_nt_qsd_owner = {
6578         "Requesting OWNER security information",
6579         "NOT requesting owner security information",
6580 };
6581
6582 static const true_false_string tfs_nt_qsd_group = {
6583         "Requesting GROUP security information",
6584         "NOT requesting group security information",
6585 };
6586
6587 static const true_false_string tfs_nt_qsd_dacl = {
6588         "Requesting DACL security information",
6589         "NOT requesting DACL security information",
6590 };
6591
6592 static const true_false_string tfs_nt_qsd_sacl = {
6593         "Requesting SACL security information",
6594         "NOT requesting SACL security information",
6595 };
6596
6597 #define NT_QSD_OWNER    0x00000001
6598 #define NT_QSD_GROUP    0x00000002
6599 #define NT_QSD_DACL     0x00000004
6600 #define NT_QSD_SACL     0x00000008
6601
6602 static int
6603 dissect_security_information_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6604 {
6605         guint32 mask;
6606         proto_item *item = NULL;
6607         proto_tree *tree = NULL;
6608
6609         mask = tvb_get_letohl(tvb, offset);
6610
6611         if(parent_tree){
6612                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6613                         "Security Information: 0x%08x", mask);
6614                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
6615         }
6616
6617         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
6618                 tvb, offset, 4, mask);
6619         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
6620                 tvb, offset, 4, mask);
6621         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
6622                 tvb, offset, 4, mask);
6623         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
6624                 tvb, offset, 4, mask);
6625
6626         offset += 4;
6627
6628         return offset;
6629 }
6630
6631 static void
6632 free_g_string(void *arg)
6633 {
6634         GString *gstring = arg;
6635
6636         g_string_free(arg, TRUE);
6637 }
6638
6639 int
6640 dissect_nt_sid(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, char *name)
6641 {
6642         proto_item *item = NULL;
6643         proto_tree *tree = NULL;
6644         int old_offset = offset, sa_offset = offset;
6645         guint *s_auths = NULL;
6646         guint rid;
6647         guint8 revision;
6648         guint8 num_auth;
6649         guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
6650         int i;
6651         GString *gstr;
6652
6653         if(parent_tree){
6654                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
6655                                            "NT %s SID", name);
6656                 tree = proto_item_add_subtree(item, ett_smb_sid);
6657         }
6658
6659         /* revision of sid */
6660         revision = tvb_get_guint8(tvb, offset);
6661         proto_tree_add_item(tree, hf_smb_sid_revision, tvb, offset, 1, TRUE);
6662         offset += 1;
6663
6664         switch(revision){
6665         case 1:  
6666         case 2:  /* Not sure what the different revision numbers mean */
6667           /* number of authorities*/
6668           num_auth = tvb_get_guint8(tvb, offset);
6669           proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, offset, 1, TRUE);
6670           offset += 1;
6671
6672           /* XXX perhaps we should have these thing searchable?
6673              a new FT_xxx thingie? SMB is quite common!*/
6674           /* identifier authorities */
6675
6676           /* FIXME: We should dynamically allocate the authorities array,
6677              which is only one thing. Then we don't have to allocate two
6678              strings below etc ...
6679           */
6680
6681           for(i=0;i<6;i++){
6682             auth = (auth << 8) + tvb_get_guint8(tvb, offset);
6683
6684             offset++;
6685           }
6686
6687           proto_tree_add_text(tree, tvb, offset - 6, 6, "Authority: %u", auth);
6688
6689           sa_offset = offset;
6690
6691           CLEANUP_PUSH(free, s_auths);
6692
6693           s_auths = g_malloc(sizeof(guint) * num_auth);
6694
6695           /* sub authorities, leave RID to last */
6696           /* FIXME: If we take an exception now, we lose the whole 
6697              sub-authorities string thang */
6698           for(i=0; i < (num_auth > 4?(num_auth - 1):num_auth); i++){
6699             /* XXX should not be letohl but native byteorder according to
6700                samba header files. considering that all non-x86 NT ports
6701                are dead we can (?) assume that non le byte encodings
6702                will be "uncommon"?*/
6703               s_auths[i] = tvb_get_letohl(tvb, offset);
6704               offset+=4;
6705           }
6706
6707           CLEANUP_CALL_AND_POP;
6708
6709           gstr = g_string_new("");
6710           
6711           for (i = 0; i < (num_auth>4?(num_auth - 1):num_auth); i++)
6712               g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"), s_auths[i]);
6713
6714           proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
6715
6716           if (num_auth > 4) {
6717             rid = tvb_get_letohl(tvb, offset);
6718             proto_tree_add_text(tree, tvb, offset, 4, "RID: %u", rid);
6719             proto_item_append_text(item, ": S-1-%u-%s-%u", auth, gstr->str, rid);
6720             offset+=4;
6721           }
6722           else {
6723             proto_item_append_text(item, ": S-1-%u-%s", auth, gstr->str);  
6724           }
6725
6726         }
6727
6728         proto_item_set_len(item, offset-old_offset);
6729         return offset;
6730 }
6731
6732
6733 static const value_string ace_type_vals[] = {
6734   { 0, "Access Allowed"},
6735   { 1, "Access Denied"},
6736   { 2, "System Audit"},
6737   { 3, "System Alarm"},
6738   { 0, NULL}
6739 };
6740 static const true_false_string tfs_ace_flags_object_inherit = {
6741   "Subordinate files will inherit this ACE",
6742   "Subordinate files will not inherit this ACE"
6743 };
6744 static const true_false_string tfs_ace_flags_container_inherit = {
6745   "Subordinate containers will inherit this ACE",
6746   "Subordinate containers will not inherit this ACE"
6747 };
6748 static const true_false_string tfs_ace_flags_non_propagate_inherit = {
6749   "Subordinate object will not propagate the inherited ACE further",
6750   "Subordinate object will propagate the inherited ACE further"
6751 };
6752 static const true_false_string tfs_ace_flags_inherit_only = {
6753   "This ACE does not apply to the current object",
6754   "This ACE applies to the current object"
6755 };
6756 static const true_false_string tfs_ace_flags_inherited_ace = {
6757   "This ACE was inherited from its parent object",
6758   "This ACE was not inherited from its parent object"
6759 };
6760 static const true_false_string tfs_ace_flags_successful_access = {
6761   "Successful accesses will be audited",
6762   "Successful accesses will not be audited"
6763 };
6764 static const true_false_string tfs_ace_flags_failed_access = {
6765   "Failed accesses will be audited",
6766   "Failed accesses will not be audited"
6767 };
6768
6769 #define APPEND_ACE_TEXT(flag, item, string) \
6770         if(flag){                                                       \
6771                 if(item)                                                \
6772                         proto_item_append_text(item, string, sep);      \
6773                 sep = ", ";                                             \
6774         }
6775
6776 static int
6777 dissect_nt_v2_ace_flags(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
6778 {
6779         proto_item *item = NULL;
6780         proto_tree *tree = NULL;
6781         guint8 mask;
6782         char *sep = " ";
6783
6784         mask = tvb_get_guint8(tvb, offset);
6785         if(parent_tree){
6786                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6787                                            "NT ACE Flags: 0x%02x", mask);
6788                 tree = proto_item_add_subtree(item, ett_smb_ace_flags);
6789         }
6790
6791         proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
6792                        tvb, offset, 1, mask);
6793         APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
6794
6795         proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
6796                        tvb, offset, 1, mask);
6797         APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
6798
6799         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
6800                        tvb, offset, 1, mask);
6801         APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
6802
6803         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
6804                        tvb, offset, 1, mask);
6805         APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
6806
6807         proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
6808                        tvb, offset, 1, mask);
6809         APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
6810
6811         proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
6812                        tvb, offset, 1, mask);
6813         APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
6814
6815         proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
6816                        tvb, offset, 1, mask);
6817         APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
6818
6819
6820         offset += 1;
6821         return offset;
6822 }
6823
6824 static int
6825 dissect_nt_v2_ace(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
6826 {
6827         proto_item *item = NULL;
6828         proto_tree *tree = NULL;
6829         int old_offset = offset;
6830         guint16 size;
6831         
6832         if(parent_tree){
6833                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
6834                                            "NT ACE: ");
6835                 tree = proto_item_add_subtree(item, ett_smb_ace);
6836         }
6837
6838         /* type */
6839         if(item){
6840           proto_item_append_text(item, val_to_str(tvb_get_guint8(tvb, offset), ace_type_vals, "Unknown ACE type (%u)"));
6841         }
6842         proto_tree_add_item(tree, hf_smb_ace_type, tvb, offset, 1, TRUE);
6843         offset += 1;
6844
6845         /* flags */
6846         offset = dissect_nt_v2_ace_flags(tvb, pinfo, offset, tree);
6847
6848         /* size */
6849         size = tvb_get_letohs(tvb, offset);
6850         proto_tree_add_uint(tree, hf_smb_ace_size, tvb, offset, 2, size);
6851         offset += 2;
6852
6853         /* access mask */
6854         offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
6855
6856         /* SID */
6857         offset = dissect_nt_sid(tvb, pinfo, offset, tree, "ACE");
6858
6859         proto_item_set_len(item, offset-old_offset);
6860
6861         /* Sometimes there is some spare space at the end of the ACE so use
6862            the size field to work out where the end is. */
6863
6864         return old_offset + size;
6865 }
6866
6867 static int
6868 dissect_nt_acl(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, char *name)
6869 {
6870         proto_item *item = NULL;
6871         proto_tree *tree = NULL;
6872         int old_offset = offset;
6873         guint16 revision, size;
6874         guint32 num_aces;
6875
6876         if(parent_tree){
6877                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
6878                                            "NT %s ACL", name);
6879                 tree = proto_item_add_subtree(item, ett_smb_acl);
6880         }
6881
6882         /* revision */
6883         revision = tvb_get_letohs(tvb, offset);
6884         proto_tree_add_uint(tree, hf_smb_acl_revision,
6885                 tvb, offset, 2, revision);
6886         offset += 2;
6887
6888         switch(revision){
6889         case 2:  /* only version we will ever see of this structure?*/
6890         case 3:
6891           /* size */
6892           proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
6893           offset += 2;
6894
6895           /* number of ace structures */
6896           num_aces = tvb_get_letohl(tvb, offset);
6897           proto_tree_add_uint(tree, hf_smb_acl_num_aces,
6898                               tvb, offset, 4, num_aces);
6899           offset += 4;
6900
6901           while(num_aces--){
6902             offset=dissect_nt_v2_ace(tvb, pinfo, offset, tree);
6903           }
6904         }
6905
6906         proto_item_set_len(item, offset-old_offset);
6907         return offset;
6908 }
6909
6910 static const true_false_string tfs_sec_desc_type_owner_defaulted = {
6911   "OWNER is DEFAULTED",
6912   "Owner is NOT defaulted"
6913 };
6914 static const true_false_string tfs_sec_desc_type_group_defaulted = {
6915   "GROUP is DEFAULTED",
6916   "Group is NOT defaulted"
6917 };
6918 static const true_false_string tfs_sec_desc_type_dacl_present = {
6919   "DACL is PRESENT",
6920   "DACL is NOT present"
6921 };
6922 static const true_false_string tfs_sec_desc_type_dacl_defaulted = {
6923   "DACL is DEFAULTED",
6924   "DACL is NOT defaulted"
6925 };
6926 static const true_false_string tfs_sec_desc_type_sacl_present = {
6927   "SACL is PRESENT",
6928   "SACL is NOT present"
6929 };
6930 static const true_false_string tfs_sec_desc_type_sacl_defaulted = {
6931   "SACL is DEFAULTED",
6932   "SACL is NOT defaulted"
6933 };
6934 static const true_false_string tfs_sec_desc_type_dacl_auto_inherit_req = {
6935   "DACL has AUTO INHERIT REQUIRED",
6936   "DACL does NOT require auto inherit"
6937 };
6938 static const true_false_string tfs_sec_desc_type_sacl_auto_inherit_req = {
6939   "SACL has AUTO INHERIT REQUIRED",
6940   "SACL does NOT require auto inherit"
6941 };
6942 static const true_false_string tfs_sec_desc_type_dacl_auto_inherited = {
6943   "DACL is AUTO INHERITED",
6944   "DACL is NOT auto inherited"
6945 };
6946 static const true_false_string tfs_sec_desc_type_sacl_auto_inherited = {
6947   "SACL is AUTO INHERITED",
6948   "SACL is NOT auto inherited"
6949 };
6950 static const true_false_string tfs_sec_desc_type_dacl_protected = {
6951   "The DACL is PROTECTED",
6952   "The DACL is NOT protected"
6953 };
6954 static const true_false_string tfs_sec_desc_type_sacl_protected = {
6955   "The SACL is PROTECTED",
6956   "The SACL is NOT protected"
6957 };
6958 static const true_false_string tfs_sec_desc_type_self_relative = {
6959   "This SecDesc is SELF RELATIVE",
6960   "This SecDesc is NOT self relative"
6961 };
6962
6963
6964 static int
6965 dissect_nt_sec_desc_type(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
6966 {
6967         proto_item *item = NULL;
6968         proto_tree *tree = NULL;
6969         guint16 mask;
6970
6971         mask = tvb_get_letohs(tvb, offset);
6972         if(parent_tree){
6973                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6974                                            "Type: 0x%04x", mask);
6975                 tree = proto_item_add_subtree(item, ett_smb_sec_desc_type);
6976         }
6977
6978         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_self_relative,
6979                                tvb, offset, 2, mask);
6980         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_protected,
6981                                tvb, offset, 2, mask);
6982         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_protected,
6983                                tvb, offset, 2, mask);
6984         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherited,
6985                                tvb, offset, 2, mask);
6986         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherited,
6987                                tvb, offset, 2, mask);
6988         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherit_req,
6989                                tvb, offset, 2, mask);
6990         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherit_req,
6991                                tvb, offset, 2, mask);
6992         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_defaulted,
6993                                tvb, offset, 2, mask);
6994         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_present,
6995                                tvb, offset, 2, mask);
6996         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_defaulted,
6997                                tvb, offset, 2, mask);
6998         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_present,
6999                                tvb, offset, 2, mask);
7000         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_group_defaulted,
7001                                tvb, offset, 2, mask);
7002         proto_tree_add_boolean(tree, hf_smb_sec_desc_type_owner_defaulted,
7003                                tvb, offset, 2, mask);
7004
7005
7006         offset += 2;
7007         return offset;
7008 }
7009
7010 /* This function is also called from DCREPC services; it may be that, in
7011    some cases, the NDR syntax must be followed, but that's not the case,
7012    for example, for the security descriptor inside an LSA Security
7013    Descriptor structure.
7014
7015    A "len" of -1 means that the NDR syntax must be followed.
7016    In that case, we assume that owner SID, group SID, SACL, and DACL objects
7017    are always stored in order (when present) and that all of them are aligned
7018    on a 4 byte boundary, and we no longer use the xxx_offset other than to
7019    check that they are non-NULL to be compatible with DCERPC NDR Unique.
7020
7021    Otherwise, we use the offsets to see where the owner SID, group SID,
7022    SACL, and DACL are stored. */
7023 int
7024 dissect_nt_sec_desc(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len)
7025 {
7026         proto_item *item = NULL;
7027         proto_tree *tree = NULL;
7028         guint16 revision;
7029         int old_offset = offset;
7030         guint32 owner_sid_offset;
7031         guint32 group_sid_offset;
7032         guint32 sacl_offset;
7033         guint32 dacl_offset;
7034
7035         if(parent_tree){
7036                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7037                                            "NT Security Descriptor");
7038                 tree = proto_item_add_subtree(item, ett_smb_sec_desc);
7039         }
7040
7041         /* revision */
7042         revision = tvb_get_letohs(tvb, offset);
7043         proto_tree_add_uint(tree, hf_smb_sec_desc_revision,
7044                 tvb, offset, 2, revision);
7045         offset += 2;
7046
7047         switch(revision){
7048         case 1:  /* only version we will ever see of this structure?*/
7049           /* type */
7050           offset = dissect_nt_sec_desc_type(tvb, pinfo, offset, tree);
7051
7052           /* offset to owner sid */
7053           owner_sid_offset = tvb_get_letohl(tvb, offset);
7054           proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %d", owner_sid_offset);
7055           offset += 4;
7056
7057           /* offset to group sid */
7058           group_sid_offset = tvb_get_letohl(tvb, offset);
7059           proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %d", group_sid_offset);
7060           offset += 4;
7061
7062           /* offset to sacl */
7063           sacl_offset = tvb_get_letohl(tvb, offset);
7064           proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %d", sacl_offset);
7065           offset += 4;
7066
7067           /* offset to dacl */
7068           dacl_offset = tvb_get_letohl(tvb, offset);
7069           proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %d", dacl_offset);
7070           offset += 4;
7071
7072           /*owner SID*/
7073           if(owner_sid_offset){
7074             if (len == -1)
7075               offset = dissect_nt_sid(tvb, pinfo, offset, tree, "Owner");
7076             else
7077               dissect_nt_sid(tvb, pinfo, old_offset+owner_sid_offset, tree, "Owner");
7078           }
7079
7080           /*group SID*/
7081           if(group_sid_offset){
7082             if (len == -1)
7083               offset = dissect_nt_sid(tvb, pinfo, offset, tree, "Group");
7084             else
7085               dissect_nt_sid(tvb, pinfo, old_offset+group_sid_offset, tree, "Group");
7086           }
7087
7088           /* sacl */
7089           if(sacl_offset){
7090             if (len == -1)
7091               offset = dissect_nt_acl(tvb, pinfo, offset, tree, "System (SACL)");
7092             else
7093               dissect_nt_acl(tvb, pinfo, old_offset+sacl_offset, tree, "System (SACL)");
7094           }
7095
7096           /* dacl */
7097           if(dacl_offset){
7098             if (len == -1)
7099               offset = dissect_nt_acl(tvb, pinfo, offset, tree, "User (DACL)");
7100             else
7101               dissect_nt_acl(tvb, pinfo, old_offset+dacl_offset, tree, "User (DACL)");
7102           }
7103
7104         }
7105
7106         if (len == -1) {
7107                 proto_item_set_len(item, offset-old_offset);
7108                 return offset;
7109         } else
7110                 return offset+len;
7111 }
7112
7113 static int
7114 dissect_nt_user_quota(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 *bcp)
7115 {
7116         int old_offset, old_sid_offset;
7117         guint32 qsize;
7118
7119         do {
7120                 old_offset=offset;
7121
7122                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7123                 qsize=tvb_get_letohl(tvb, offset);
7124                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
7125                 COUNT_BYTES_TRANS_SUBR(4);
7126
7127                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7128                 /* length of SID */
7129                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7130                 COUNT_BYTES_TRANS_SUBR(4);
7131
7132                 /* 16 unknown bytes */
7133                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7134                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7135                             offset, 8, TRUE);
7136                 COUNT_BYTES_TRANS_SUBR(8);
7137
7138                 /* number of bytes for used quota */
7139                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7140                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
7141                 COUNT_BYTES_TRANS_SUBR(8);
7142
7143                 /* number of bytes for quota warning */
7144                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7145                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
7146                 COUNT_BYTES_TRANS_SUBR(8);
7147
7148                 /* number of bytes for quota limit */
7149                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7150                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
7151                 COUNT_BYTES_TRANS_SUBR(8);
7152
7153                 /* SID of the user */
7154                 old_sid_offset=offset;
7155                 offset = dissect_nt_sid(tvb, pinfo, offset, tree, "Quota");
7156                 *bcp -= (offset-old_sid_offset);
7157
7158                 if(qsize){
7159                         offset = old_offset+qsize;
7160                 }
7161         }while(qsize);
7162
7163
7164         return offset;
7165 }
7166
7167
7168 static int
7169 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
7170 {
7171         proto_item *item = NULL;
7172         proto_tree *tree = NULL;
7173         smb_info_t *si;
7174         int old_offset = offset;
7175         guint16 bcp=bc; /* XXX fixme */
7176
7177         si = (smb_info_t *)pinfo->private_data;
7178
7179         if(parent_tree){
7180                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
7181                                 "%s Data",
7182                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7183                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7184         }
7185
7186         switch(ntd->subcmd){
7187         case NT_TRANS_CREATE:
7188                 /* security descriptor */
7189                 if(ntd->sd_len){
7190                         offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, ntd->sd_len);
7191                 }
7192
7193                 /* extended attributes */
7194                 if(ntd->ea_len){
7195                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
7196                         offset += ntd->ea_len;
7197                 }
7198
7199                 break;
7200         case NT_TRANS_IOCTL:
7201                 /* ioctl data */
7202                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
7203                 offset += bc;
7204
7205                 break;
7206         case NT_TRANS_SSD:
7207                 offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, bc);
7208                 break;
7209         case NT_TRANS_NOTIFY:
7210                 break;
7211         case NT_TRANS_RENAME:
7212                 /* XXX not documented */
7213                 break;
7214         case NT_TRANS_QSD:
7215                 break;
7216         case NT_TRANS_GET_USER_QUOTA:
7217                 /* unknown 4 bytes */
7218                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7219                             offset, 4, TRUE);
7220                 offset += 4;
7221
7222                 /* length of SID */
7223                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7224                 offset +=4;
7225
7226                 offset = dissect_nt_sid(tvb, pinfo, offset, tree, "Quota");
7227                 break;
7228         case NT_TRANS_SET_USER_QUOTA:
7229                 offset = dissect_nt_user_quota(tvb, pinfo, tree, offset, &bcp);
7230                 break;
7231         }
7232
7233         /* ooops there were data we didnt know how to process */
7234         if((offset-old_offset) < bc){
7235                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
7236                     bc - (offset-old_offset), TRUE);
7237                 offset += bc - (offset-old_offset);
7238         }
7239
7240         return offset;
7241 }
7242
7243 static int
7244 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)
7245 {
7246         proto_item *item = NULL;
7247         proto_tree *tree = NULL;
7248         smb_info_t *si;
7249         guint32 fn_len;
7250         const char *fn;
7251
7252         si = (smb_info_t *)pinfo->private_data;
7253
7254         if(parent_tree){
7255                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7256                                 "%s Parameters",
7257                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7258                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7259         }
7260
7261         switch(ntd->subcmd){
7262         case NT_TRANS_CREATE:
7263                 /* Create flags */
7264                 offset = dissect_nt_create_bits(tvb, pinfo, tree, offset);
7265                 bc -= 4;
7266
7267                 /* root directory fid */
7268                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
7269                 COUNT_BYTES(4);
7270
7271                 /* nt access mask */
7272                 offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
7273                 bc -= 4;
7274         
7275                 /* allocation size */
7276                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7277                 COUNT_BYTES(8);
7278         
7279                 /* Extended File Attributes */
7280                 offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
7281                 bc -= 4;
7282
7283                 /* share access */
7284                 offset = dissect_nt_share_access(tvb, pinfo, tree, offset);
7285                 bc -= 4;
7286         
7287                 /* create disposition */
7288                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
7289                 COUNT_BYTES(4);
7290
7291                 /* create options */
7292                 offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
7293                 bc -= 4;
7294
7295                 /* sd length */
7296                 ntd->sd_len = tvb_get_letohl(tvb, offset);
7297                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
7298                 COUNT_BYTES(4);
7299
7300                 /* ea length */
7301                 ntd->ea_len = tvb_get_letohl(tvb, offset);
7302                 proto_tree_add_uint(tree, hf_smb_ea_length, tvb, offset, 4, ntd->ea_len);
7303                 COUNT_BYTES(4);
7304
7305                 /* file name len */
7306                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
7307                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
7308                 COUNT_BYTES(4);
7309
7310                 /* impersonation level */
7311                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
7312                 COUNT_BYTES(4);
7313         
7314                 /* security flags */
7315                 offset = dissect_nt_security_flags(tvb, pinfo, tree, offset);
7316                 bc -= 1;
7317
7318                 /* file name */
7319                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, &bc);
7320                 if (fn != NULL) {
7321                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7322                                 fn);
7323                         COUNT_BYTES(fn_len);
7324                 }
7325
7326                 break;
7327         case NT_TRANS_IOCTL:
7328                 break;
7329         case NT_TRANS_SSD: {
7330                 guint16 fid;
7331
7332                 /* fid */
7333                 fid = tvb_get_letohs(tvb, offset);
7334                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7335                 offset += 2;
7336
7337                 /* 2 reserved bytes */
7338                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7339                 offset += 2;
7340
7341                 /* security information */
7342                 offset = dissect_security_information_mask(tvb, pinfo, tree, offset);
7343                 break;
7344         }
7345         case NT_TRANS_NOTIFY:
7346                 break;
7347         case NT_TRANS_RENAME:
7348                 /* XXX not documented */
7349                 break;
7350         case NT_TRANS_QSD: {
7351                 guint16 fid;
7352
7353                 /* fid */
7354                 fid = tvb_get_letohs(tvb, offset);
7355                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7356                 offset += 2;
7357
7358                 /* 2 reserved bytes */
7359                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7360                 offset += 2;
7361
7362                 /* security information */
7363                 offset = dissect_security_information_mask(tvb, pinfo, tree, offset);
7364                 break;
7365         }
7366         case NT_TRANS_GET_USER_QUOTA:
7367                 /* not decoded yet */
7368                 break;
7369         case NT_TRANS_SET_USER_QUOTA:
7370                 /* not decoded yet */
7371                 break;
7372         }
7373
7374         return offset;
7375 }
7376
7377 static int
7378 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7379 {
7380         proto_item *item = NULL;
7381         proto_tree *tree = NULL;
7382         smb_info_t *si;
7383         int old_offset = offset;
7384
7385         si = (smb_info_t *)pinfo->private_data;
7386
7387         if(parent_tree){
7388                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7389                                 "%s Setup",
7390                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7391                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
7392         }
7393  
7394         switch(ntd->subcmd){
7395         case NT_TRANS_CREATE:
7396                 break;
7397         case NT_TRANS_IOCTL: {
7398                 guint16 fid;
7399
7400                 /* function code */
7401                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
7402                 offset += 4;
7403
7404                 /* fid */
7405                 fid = tvb_get_letohs(tvb, offset);
7406                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7407                 offset += 2;
7408
7409                 /* isfsctl */
7410                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
7411                 offset += 1;
7412
7413                 /* isflags */
7414                 offset = dissect_nt_ioctl_flags(tvb, pinfo, tree, offset);
7415
7416                 break;
7417         }
7418         case NT_TRANS_SSD:
7419                 break;
7420         case NT_TRANS_NOTIFY: {
7421                 guint16 fid;
7422
7423                 /* completion filter */
7424                 offset = dissect_nt_notify_completion_filter(tvb, pinfo, tree, offset);
7425
7426                 /* fid */
7427                 fid = tvb_get_letohs(tvb, offset);
7428                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7429                 offset += 2;
7430
7431                 /* watch tree */
7432                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
7433                 offset += 1;
7434
7435                 /* reserved byte */
7436                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7437                 offset += 1;
7438
7439                 break;
7440         }
7441         case NT_TRANS_RENAME:
7442                 /* XXX not documented */
7443                 break;
7444         case NT_TRANS_QSD:
7445                 break;
7446         case NT_TRANS_GET_USER_QUOTA:
7447                 /* not decoded yet */
7448                 break;
7449         case NT_TRANS_SET_USER_QUOTA:
7450                 /* not decoded yet */
7451                 break;
7452         }
7453  
7454         return old_offset+len;
7455 }
7456
7457
7458 static int
7459 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7460 {
7461         guint8 wc, sc;
7462         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
7463         smb_info_t *si;
7464         smb_saved_info_t *sip;
7465         int subcmd;
7466         nt_trans_data ntd;
7467         guint16 bc;
7468         int padcnt;
7469         smb_nt_transact_info_t *nti;
7470
7471         si = (smb_info_t *)pinfo->private_data;
7472         sip = si->sip;
7473
7474         WORD_COUNT;
7475
7476         if(wc>=19){
7477                 /* primary request */
7478                 /* max setup count */
7479                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
7480                 offset += 1;
7481
7482                 /* 2 reserved bytes */
7483                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7484                 offset += 2;
7485         } else {
7486                 /* secondary request */
7487                 /* 3 reserved bytes */
7488                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
7489                 offset += 3;
7490         }
7491
7492
7493         /* total param count */
7494         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
7495         offset += 4;
7496         
7497         /* total data count */
7498         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
7499         offset += 4;
7500
7501         if(wc>=19){
7502                 /* primary request */
7503                 /* max param count */
7504                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
7505                 offset += 4;
7506
7507                 /* max data count */
7508                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
7509                 offset += 4;
7510         }
7511
7512         /* param count */
7513         pc = tvb_get_letohl(tvb, offset);
7514         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
7515         offset += 4;
7516         
7517         /* param offset */
7518         po = tvb_get_letohl(tvb, offset);
7519         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
7520         offset += 4;
7521
7522         /* param displacement */
7523         if(wc>=19){
7524                 /* primary request*/
7525                 pd = 0;
7526         } else {
7527                 /* secondary request */
7528                 pd = tvb_get_letohl(tvb, offset);
7529                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
7530                 offset += 4;
7531         }
7532
7533         /* data count */
7534         dc = tvb_get_letohl(tvb, offset);
7535         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
7536         offset += 4;
7537
7538         /* data offset */
7539         od = tvb_get_letohl(tvb, offset);
7540         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
7541         offset += 4;
7542
7543         /* data displacement */
7544         if(wc>=19){
7545                 /* primary request */
7546                 dd = 0;
7547         } else {
7548                 /* secondary request */
7549                 dd = tvb_get_letohl(tvb, offset);
7550                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
7551                 offset += 4;
7552         }
7553
7554         /* setup count */
7555         if(wc>=19){
7556                 /* primary request */
7557                 sc = tvb_get_guint8(tvb, offset);
7558                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
7559                 offset += 1;
7560         } else {
7561                 /* secondary request */
7562                 sc = 0;
7563         }
7564
7565         /* function */
7566         if(wc>=19){
7567                 /* primary request */
7568                 subcmd = tvb_get_letohs(tvb, offset);
7569                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
7570                 if(check_col(pinfo->cinfo, COL_INFO)){
7571                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
7572                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
7573                 }
7574                 ntd.subcmd = subcmd;
7575                 if (!si->unidir) {
7576                         if(!pinfo->fd->flags.visited){
7577                                 /* 
7578                                  * Allocate a new smb_nt_transact_info_t
7579                                  * structure.
7580                                  */
7581                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
7582                                 nti->subcmd = subcmd;
7583                                 sip->extra_info = nti;
7584                         }
7585                 }
7586         } else {
7587                 /* secondary request */
7588                 if(check_col(pinfo->cinfo, COL_INFO)){
7589                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
7590                 }
7591         }
7592         offset += 2;
7593
7594         /* this is a padding byte */
7595         if(offset%1){
7596                 /* pad byte */
7597                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
7598                 offset += 1;
7599         }
7600
7601         /* if there were any setup bytes, decode them */
7602         if(sc){
7603                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
7604                 offset += sc*2;
7605         }
7606
7607         BYTE_COUNT;
7608         
7609         /* parameters */
7610         if(po>(guint32)offset){
7611                 /* We have some initial padding bytes.
7612                 */
7613                 padcnt = po-offset;
7614                 if (padcnt > bc)
7615                         padcnt = bc;
7616                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7617                 COUNT_BYTES(padcnt);
7618         }
7619         if(pc){
7620                 CHECK_BYTE_COUNT(pc);
7621                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
7622                 COUNT_BYTES(pc);
7623         }
7624
7625         /* data */
7626         if(od>(guint32)offset){
7627                 /* We have some initial padding bytes.
7628                 */
7629                 padcnt = od-offset;
7630                 if (padcnt > bc)
7631                         padcnt = bc;
7632                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7633                 COUNT_BYTES(padcnt);
7634         }
7635         if(dc){
7636                 CHECK_BYTE_COUNT(dc);
7637                 dissect_nt_trans_data_request(tvb, pinfo, offset, tree, dc, &ntd);
7638                 COUNT_BYTES(dc);
7639         }
7640
7641         END_OF_SMB
7642
7643         return offset;
7644 }
7645
7646
7647
7648 static int
7649 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7650 {
7651         proto_item *item = NULL;
7652         proto_tree *tree = NULL;
7653         smb_info_t *si;
7654         smb_nt_transact_info_t *nti;
7655         guint16 bcp;
7656
7657         si = (smb_info_t *)pinfo->private_data;
7658         if (si->sip != NULL)
7659                 nti = si->sip->extra_info;
7660         else
7661                 nti = NULL;
7662
7663         if(parent_tree){
7664                 if(nti != NULL){
7665                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7666                                 "%s Data",
7667                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7668                 } else {
7669                         /*
7670                          * We never saw the request to which this is a
7671                          * response.
7672                          */
7673                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7674                                 "Unknown NT Transaction Data (matching request not seen)");
7675                 }
7676                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
7677         }
7678
7679         if (nti == NULL) {
7680                 offset += len;
7681                 return offset;
7682         }
7683         switch(nti->subcmd){
7684         case NT_TRANS_CREATE:
7685                 break;
7686         case NT_TRANS_IOCTL:
7687                 /* ioctl data */
7688                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
7689                 offset += len;
7690
7691                 break;
7692         case NT_TRANS_SSD:
7693                 break;
7694         case NT_TRANS_NOTIFY:
7695                 break;
7696         case NT_TRANS_RENAME:
7697                 /* XXX not documented */
7698                 break;
7699         case NT_TRANS_QSD:
7700                 /*
7701                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
7702                  * which may be documented in the Win32 documentation
7703                  * somewhere.
7704                  */
7705                 offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, len);
7706                 break;
7707         case NT_TRANS_GET_USER_QUOTA:
7708                 bcp=len;
7709                 offset = dissect_nt_user_quota(tvb, pinfo, tree, offset, &bcp);
7710                 break;
7711         case NT_TRANS_SET_USER_QUOTA:
7712                 /* not decoded yet */
7713                 break;
7714         }
7715
7716         return offset;
7717 }
7718  
7719 static int
7720 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd, guint16 bc)
7721 {
7722         proto_item *item = NULL;
7723         proto_tree *tree = NULL;
7724         guint32 fn_len;
7725         const char *fn;
7726         smb_info_t *si;
7727         smb_nt_transact_info_t *nti;
7728         guint16 fid;
7729         int old_offset;
7730         guint32 neo;
7731         int padcnt;
7732
7733         si = (smb_info_t *)pinfo->private_data;
7734         if (si->sip != NULL)
7735                 nti = si->sip->extra_info;
7736         else
7737                 nti = NULL;
7738
7739         if(parent_tree){
7740                 if(nti != NULL){
7741                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7742                                 "%s Parameters",
7743                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7744                 } else {
7745                         /*
7746                          * We never saw the request to which this is a
7747                          * response.
7748                          */
7749                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7750                                 "Unknown NT Transaction Parameters (matching request not seen)");
7751                 }
7752                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
7753         }
7754
7755         if (nti == NULL) {
7756                 offset += len;
7757                 return offset;
7758         }
7759         switch(nti->subcmd){
7760         case NT_TRANS_CREATE:
7761                 /* oplock level */
7762                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
7763                 offset += 1;
7764
7765                 /* reserved byte */
7766                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7767                 offset += 1;
7768                 
7769                 /* fid */
7770                 fid = tvb_get_letohs(tvb, offset);
7771                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7772                 offset += 2;
7773
7774                 /* create action */
7775                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
7776                 offset += 4;
7777
7778                 /* ea error offset */
7779                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
7780                 offset += 4;
7781
7782                 /* create time */
7783                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7784                         hf_smb_create_time);
7785         
7786                 /* access time */
7787                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7788                         hf_smb_access_time);
7789         
7790                 /* last write time */
7791                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7792                         hf_smb_last_write_time);
7793         
7794                 /* last change time */
7795                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7796                         hf_smb_change_time);
7797         
7798                 /* Extended File Attributes */
7799                 offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
7800
7801                 /* allocation size */
7802                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7803                 offset += 8;
7804
7805                 /* end of file */
7806                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
7807                 offset += 8;
7808
7809                 /* File Type */
7810                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
7811                 offset += 2;
7812
7813                 /* device state */
7814                 offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
7815
7816                 /* is directory */
7817                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
7818                 offset += 1;
7819                 break;
7820         case NT_TRANS_IOCTL:
7821                 break;
7822         case NT_TRANS_SSD:
7823                 break;
7824         case NT_TRANS_NOTIFY:
7825                 while(len){
7826                         old_offset = offset;
7827
7828                         /* next entry offset */
7829                         neo = tvb_get_letohl(tvb, offset);
7830                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
7831                         COUNT_BYTES(4);
7832                         len -= 4;
7833                         /* broken implementations */
7834                         if(len<0)break;
7835         
7836                         /* action */
7837                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
7838                         COUNT_BYTES(4);
7839                         len -= 4;
7840                         /* broken implementations */
7841                         if(len<0)break;
7842
7843                         /* file name len */
7844                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
7845                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
7846                         COUNT_BYTES(4);
7847                         len -= 4;
7848                         /* broken implementations */
7849                         if(len<0)break;
7850
7851                         /* file name */
7852                         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, &bc);
7853                         if (fn == NULL)
7854                                 break;
7855                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7856                                 fn);
7857                         COUNT_BYTES(fn_len);
7858                         len -= fn_len;
7859                         /* broken implementations */
7860                         if(len<0)break;
7861
7862                         if (neo == 0)
7863                                 break;  /* no more structures */
7864
7865                         /* skip to next structure */
7866                         padcnt = (old_offset + neo) - offset;
7867                         if (padcnt < 0) {
7868                                 /*
7869                                  * XXX - this is bogus; flag it?
7870                                  */
7871                                 padcnt = 0;
7872                         }
7873                         if (padcnt != 0) {
7874                                 COUNT_BYTES(padcnt);
7875                                 len -= padcnt;
7876                                 /* broken implementations */
7877                                 if(len<0)break;
7878                         }
7879                 }
7880                 break;
7881         case NT_TRANS_RENAME:
7882                 /* XXX not documented */
7883                 break;
7884         case NT_TRANS_QSD:
7885                 /*
7886                  * This appears to be the size of the security
7887                  * descriptor; the calling sequence of
7888                  * "ZwQuerySecurityObject()" suggests that it would
7889                  * be.  The actual security descriptor wouldn't
7890                  * follow if the max data count in the request
7891                  * was smaller; this lets the client know how
7892                  * big a buffer it needs to provide.
7893                  */
7894                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
7895                 offset += 4;
7896                 break;
7897         case NT_TRANS_GET_USER_QUOTA:
7898                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
7899                         tvb_get_letohl(tvb, offset));
7900                 offset += 4;
7901                 break;
7902         case NT_TRANS_SET_USER_QUOTA:
7903                 /* not decoded yet */
7904                 break;
7905         }
7906
7907         return offset;
7908 }
7909  
7910 static int
7911 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7912 {
7913         proto_item *item = NULL;
7914         proto_tree *tree = NULL;
7915         smb_info_t *si;
7916         smb_nt_transact_info_t *nti;
7917
7918         si = (smb_info_t *)pinfo->private_data;
7919         if (si->sip != NULL)
7920                 nti = si->sip->extra_info;
7921         else
7922                 nti = NULL;
7923
7924         if(parent_tree){
7925                 if(nti != NULL){
7926                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7927                                 "%s Setup",
7928                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7929                 } else {
7930                         /*
7931                          * We never saw the request to which this is a
7932                          * response.
7933                          */
7934                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7935                                 "Unknown NT Transaction Setup (matching request not seen)");
7936                 }
7937                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
7938         }
7939
7940         if (nti == NULL) {
7941                 offset += len;
7942                 return offset;
7943         }
7944         switch(nti->subcmd){
7945         case NT_TRANS_CREATE:
7946                 break;
7947         case NT_TRANS_IOCTL:
7948                 break;
7949         case NT_TRANS_SSD:
7950                 break;
7951         case NT_TRANS_NOTIFY:
7952                 break;
7953         case NT_TRANS_RENAME:
7954                 /* XXX not documented */
7955                 break;
7956         case NT_TRANS_QSD:
7957                 break;
7958         case NT_TRANS_GET_USER_QUOTA:
7959                 /* not decoded yet */
7960                 break;
7961         case NT_TRANS_SET_USER_QUOTA:
7962                 /* not decoded yet */
7963                 break;
7964         }
7965
7966         return offset;
7967 }
7968
7969 static int
7970 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7971 {
7972         guint8 wc, sc;
7973         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
7974         guint32 td=0, tp=0;
7975         smb_info_t *si;
7976         smb_nt_transact_info_t *nti;
7977         static nt_trans_data ntd;
7978         guint16 bc;
7979         int padcnt;
7980         fragment_data *r_fd = NULL;
7981         tvbuff_t *pd_tvb=NULL;
7982         gboolean save_fragmented;
7983
7984         si = (smb_info_t *)pinfo->private_data;
7985         if (si->sip != NULL)
7986                 nti = si->sip->extra_info;
7987         else
7988                 nti = NULL;
7989
7990         /* primary request */
7991         if(nti != NULL){
7992                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
7993                 if(check_col(pinfo->cinfo, COL_INFO)){
7994                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
7995                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
7996                 }
7997         } else {
7998                 proto_tree_add_text(tree, tvb, offset, 0,
7999                         "Function: <unknown function - could not find matching request>");
8000                 if(check_col(pinfo->cinfo, COL_INFO)){
8001                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
8002                 }
8003         }
8004
8005         WORD_COUNT;
8006
8007         /* 3 reserved bytes */
8008         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8009         offset += 3;
8010
8011         /* total param count */
8012         tp = tvb_get_letohl(tvb, offset);
8013         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8014         offset += 4;
8015         
8016         /* total data count */
8017         td = tvb_get_letohl(tvb, offset);
8018         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8019         offset += 4;
8020
8021         /* param count */
8022         pc = tvb_get_letohl(tvb, offset);
8023         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8024         offset += 4;
8025         
8026         /* param offset */
8027         po = tvb_get_letohl(tvb, offset);
8028         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8029         offset += 4;
8030
8031         /* param displacement */
8032         pd = tvb_get_letohl(tvb, offset);
8033         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8034         offset += 4;
8035
8036         /* data count */
8037         dc = tvb_get_letohl(tvb, offset);
8038         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8039         offset += 4;
8040
8041         /* data offset */
8042         od = tvb_get_letohl(tvb, offset);
8043         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8044         offset += 4;
8045
8046         /* data displacement */
8047         dd = tvb_get_letohl(tvb, offset);
8048         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8049         offset += 4;
8050
8051         /* setup count */
8052         sc = tvb_get_guint8(tvb, offset);
8053         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8054         offset += 1;
8055
8056         /* setup data */        
8057         if(sc){
8058                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
8059                 offset += sc*2;
8060         }
8061
8062         BYTE_COUNT;
8063
8064         /* reassembly of SMB NT Transaction data payload.
8065            In this section we do reassembly of both the data and parameters
8066            blocks of the SMB transaction command.
8067         */
8068         save_fragmented = pinfo->fragmented;
8069         /* do we need reassembly? */
8070         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
8071                 /* oh yeah, either data or parameter section needs 
8072                    reassembly...
8073                 */
8074                 pinfo->fragmented = TRUE;
8075                 if(smb_trans_reassembly){
8076                         /* ...and we were told to do reassembly */
8077                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
8078                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
8079                                                              po, pc, pd, td+tp);
8080                                 
8081                         }
8082                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
8083                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
8084                                                              od, dc, dd+tp, td+tp);
8085                         }
8086                 }
8087         }
8088
8089         /* if we got a reassembled fd structure from the reassembly routine we
8090            must create pd_tvb from it 
8091         */
8092         if(r_fd){
8093                 proto_tree *tr;
8094                 proto_item *it;
8095                 fragment_data *fd;
8096                 
8097                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
8098                                              r_fd->datalen);
8099                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
8100                 add_new_data_source(pinfo->fd, pd_tvb, "Reassembled SMB");
8101                 pinfo->fragmented = FALSE;
8102
8103                 it = proto_tree_add_text(tree, pd_tvb, 0, -1, "Fragments");
8104                 tr = proto_item_add_subtree(it, ett_smb_segments);
8105                 for(fd=r_fd->next;fd;fd=fd->next){
8106                         proto_tree_add_text(tr, pd_tvb, fd->offset, fd->len,
8107                                             "Frame:%u Data:%u-%u",
8108                                             fd->frame, fd->offset,
8109                                             fd->offset+fd->len-1);
8110                 }
8111         }
8112
8113
8114         if(pd_tvb){
8115           /* we have reassembled data, grab param and data from there */
8116           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
8117                                           &ntd, tvb_length(pd_tvb));
8118           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
8119         } else {
8120           /* we do not have reassembled data, just use what we have in the 
8121              packet as well as we can */
8122           /* parameters */
8123           if(po>(guint32)offset){
8124             /* We have some initial padding bytes.
8125              */
8126             padcnt = po-offset;
8127             if (padcnt > bc)
8128               padcnt = bc;
8129             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8130             COUNT_BYTES(padcnt);
8131           }
8132           if(pc){
8133             CHECK_BYTE_COUNT(pc);
8134             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
8135             COUNT_BYTES(pc);
8136           }
8137           
8138           /* data */
8139           if(od>(guint32)offset){
8140             /* We have some initial padding bytes.
8141              */
8142             padcnt = od-offset;
8143             if (padcnt > bc)
8144               padcnt = bc;
8145             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8146             COUNT_BYTES(padcnt);
8147           }
8148           if(dc){
8149             CHECK_BYTE_COUNT(dc);
8150             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
8151             COUNT_BYTES(dc);
8152           }
8153         }
8154         pinfo->fragmented = save_fragmented;
8155
8156         END_OF_SMB
8157
8158         return offset;
8159 }
8160
8161 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8162    NT Transaction command  ends here
8163    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8164
8165 static const value_string print_mode_vals[] = {
8166         {0,     "Text Mode"},
8167         {1,     "Graphics Mode"},
8168         {0, NULL}
8169 };
8170  
8171 static int
8172 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8173 {
8174         int fn_len;
8175         const char *fn;
8176         guint8 wc;
8177         guint16 bc;
8178
8179         WORD_COUNT;
8180
8181         /* setup len */
8182         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
8183         offset += 2;
8184
8185         /* print mode */
8186         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
8187         offset += 2;
8188
8189         BYTE_COUNT;
8190
8191         /* buffer format */
8192         CHECK_BYTE_COUNT(1);
8193         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8194         COUNT_BYTES(1);
8195
8196         /* print identifier */
8197         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, FALSE, &bc);
8198         if (fn == NULL)
8199                 goto endofcommand;
8200         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
8201                 fn);
8202         COUNT_BYTES(fn_len);
8203
8204         END_OF_SMB
8205
8206         return offset;
8207 }
8208
8209
8210 static int
8211 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8212 {
8213         int cnt;
8214         guint8 wc;
8215         guint16 bc, fid;
8216
8217         WORD_COUNT;
8218
8219         /* fid */
8220         fid = tvb_get_letohs(tvb, offset);
8221         add_fid(tvb, pinfo, tree, offset, 2, fid);
8222         offset += 2;
8223
8224         BYTE_COUNT;
8225
8226         /* buffer format */
8227         CHECK_BYTE_COUNT(1);
8228         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8229         COUNT_BYTES(1);
8230
8231         /* data len */
8232         CHECK_BYTE_COUNT(2);
8233         cnt = tvb_get_letohs(tvb, offset);
8234         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
8235         COUNT_BYTES(2);
8236
8237         /* file data */
8238         offset = dissect_file_data(tvb, pinfo, tree, offset, cnt, cnt);
8239
8240         END_OF_SMB
8241
8242         return offset;
8243 }
8244
8245
8246 static const value_string print_status_vals[] = {
8247         {1,     "Held or Stopped"},
8248         {2,     "Printing"},
8249         {3,     "Awaiting print"},
8250         {4,     "In intercept"},
8251         {5,     "File had error"},
8252         {6,     "Printer error"},
8253         {0, NULL}
8254 };
8255  
8256 static int
8257 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8258 {
8259         guint8 wc;
8260         guint16 bc;
8261
8262         WORD_COUNT;
8263
8264         /* max count */
8265         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
8266         offset += 2;
8267
8268         /* start index */
8269         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
8270         offset += 2;
8271
8272         BYTE_COUNT;
8273
8274         END_OF_SMB
8275
8276         return offset;
8277 }
8278
8279 static int
8280 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
8281     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
8282 {
8283         proto_item *item = NULL;
8284         proto_tree *tree = NULL;
8285         int fn_len;
8286         const char *fn;
8287
8288         if(parent_tree){
8289                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
8290                         "Queue entry");
8291                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
8292         }
8293
8294         /* queued time */
8295         CHECK_BYTE_COUNT_SUBR(4);
8296         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
8297                 hf_smb_print_queue_date,
8298                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
8299         *bcp -= 4;
8300
8301         /* status */
8302         CHECK_BYTE_COUNT_SUBR(1);
8303         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
8304         COUNT_BYTES_SUBR(1);
8305
8306         /* spool file number */
8307         CHECK_BYTE_COUNT_SUBR(2);
8308         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
8309         COUNT_BYTES_SUBR(2);
8310
8311         /* spool file size */
8312         CHECK_BYTE_COUNT_SUBR(4);
8313         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
8314         COUNT_BYTES_SUBR(4);
8315
8316         /* reserved byte */
8317         CHECK_BYTE_COUNT_SUBR(1);
8318         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8319         COUNT_BYTES_SUBR(1);
8320
8321         /* file name */
8322         fn_len = 16;
8323         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, bcp);
8324         CHECK_STRING_SUBR(fn);
8325         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
8326                 fn);
8327         COUNT_BYTES_SUBR(fn_len);
8328
8329         *trunc = FALSE;
8330         return offset;
8331 }
8332
8333 static int
8334 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8335 {
8336         guint16 cnt=0, len;
8337         guint8 wc;
8338         guint16 bc;
8339         gboolean trunc;
8340
8341         WORD_COUNT;
8342
8343         /* count */
8344         cnt = tvb_get_letohs(tvb, offset);
8345         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
8346         offset += 2;
8347
8348         /* restart index */
8349         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
8350         offset += 2;
8351
8352         BYTE_COUNT;
8353
8354         /* buffer format */
8355         CHECK_BYTE_COUNT(1);
8356         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
8357         COUNT_BYTES(1);
8358
8359         /* data len */
8360         CHECK_BYTE_COUNT(2);
8361         len = tvb_get_letohs(tvb, offset);
8362         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
8363         COUNT_BYTES(2);
8364
8365         /* queue elements */
8366         while(cnt--){
8367                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
8368                     &bc, &trunc);
8369                 if (trunc)
8370                         goto endofcommand;
8371         }
8372
8373         END_OF_SMB
8374
8375         return offset;
8376 }
8377
8378
8379 static int
8380 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8381 {
8382         guint8  wc, cmd=0xff;
8383         guint16 andxoffset=0;
8384         guint16 bc;
8385         int fn_len;
8386         const char *fn;
8387
8388         WORD_COUNT;
8389
8390         /* next smb command */
8391         cmd = tvb_get_guint8(tvb, offset);
8392         if(cmd!=0xff){
8393                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
8394         } else {
8395                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
8396         }
8397         offset += 1;
8398
8399         /* reserved byte */
8400         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8401         offset += 1;
8402
8403         /* andxoffset */
8404         andxoffset = tvb_get_letohs(tvb, offset);
8405         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8406         offset += 2;
8407
8408         /* reserved byte */
8409         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8410         offset += 1;
8411
8412         /* file name len */
8413         fn_len = tvb_get_letohs(tvb, offset);
8414         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
8415         offset += 2;
8416
8417         /* Create flags */
8418         offset = dissect_nt_create_bits(tvb, pinfo, tree, offset);
8419
8420         /* root directory fid */
8421         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
8422         offset += 4;
8423
8424         /* nt access mask */
8425         offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
8426
8427         /* allocation size */
8428         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8429         offset += 8;
8430
8431         /* Extended File Attributes */
8432         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
8433
8434         /* share access */
8435         offset = dissect_nt_share_access(tvb, pinfo, tree, offset);
8436
8437         /* create disposition */
8438         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8439         offset += 4;
8440
8441         /* create options */
8442         offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
8443
8444         /* impersonation level */
8445         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8446         offset += 4;
8447
8448         /* security flags */
8449         offset = dissect_nt_security_flags(tvb, pinfo, tree, offset);
8450
8451         BYTE_COUNT;
8452
8453         /* file name */
8454         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8455         if (fn == NULL)
8456                 goto endofcommand;
8457         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8458                 fn);
8459         COUNT_BYTES(fn_len);
8460
8461         if (check_col(pinfo->cinfo, COL_INFO)) {
8462                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
8463         }
8464
8465         END_OF_SMB
8466
8467         /* call AndXCommand (if there are any) */
8468         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
8469
8470         return offset;
8471 }
8472  
8473
8474 static int
8475 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8476 {
8477         guint8  wc, cmd=0xff;
8478         guint16 andxoffset=0;
8479         guint16 bc;
8480         guint16 fid;
8481
8482         WORD_COUNT;
8483
8484         /* next smb command */
8485         cmd = tvb_get_guint8(tvb, offset);
8486         if(cmd!=0xff){
8487                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
8488         } else {
8489                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
8490         }
8491         offset += 1;
8492
8493         /* reserved byte */
8494         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8495         offset += 1;
8496
8497         /* andxoffset */
8498         andxoffset = tvb_get_letohs(tvb, offset);
8499         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8500         offset += 2;
8501
8502         /* oplock level */
8503         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8504         offset += 1;
8505
8506         /* fid */
8507         fid = tvb_get_letohs(tvb, offset);
8508         add_fid(tvb, pinfo, tree, offset, 2, fid);
8509         offset += 2;
8510
8511         /* create action */
8512         /*XXX is this really the same as create disposition in the request? it looks so*/
8513         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8514         offset += 4;
8515
8516         /* create time */
8517         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8518                 hf_smb_create_time);
8519         
8520         /* access time */
8521         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8522                 hf_smb_access_time);
8523         
8524         /* last write time */
8525         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8526                 hf_smb_last_write_time);
8527
8528         /* last change time */
8529         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8530                 hf_smb_change_time);
8531         
8532         /* Extended File Attributes */
8533         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
8534
8535         /* allocation size */
8536         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8537         offset += 8;
8538
8539         /* end of file */
8540         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8541         offset += 8;
8542
8543         /* File Type */
8544         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8545         offset += 2;
8546
8547         /* IPC State */
8548         offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
8549
8550         /* is directory */
8551         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8552         offset += 1;
8553
8554         BYTE_COUNT;
8555
8556         END_OF_SMB
8557
8558         /* call AndXCommand (if there are any) */
8559         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
8560
8561         return offset;
8562 }
8563
8564
8565 static int
8566 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8567 {
8568         guint8 wc;
8569         guint16 bc;
8570
8571         WORD_COUNT;
8572  
8573         BYTE_COUNT;
8574
8575         END_OF_SMB
8576
8577         return offset;
8578 }
8579
8580 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8581    BEGIN Transaction/Transaction2 Primary and secondary requests
8582    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8583
8584
8585 static const value_string trans2_cmd_vals[] = {
8586         { 0x00,         "OPEN2" },
8587         { 0x01,         "FIND_FIRST2" },
8588         { 0x02,         "FIND_NEXT2" },
8589         { 0x03,         "QUERY_FS_INFORMATION" },
8590         { 0x04,         "SET_FS_QUOTA" },
8591         { 0x05,         "QUERY_PATH_INFORMATION" },
8592         { 0x06,         "SET_PATH_INFORMATION" },
8593         { 0x07,         "QUERY_FILE_INFORMATION" },
8594         { 0x08,         "SET_FILE_INFORMATION" },
8595         { 0x09,         "FSCTL" },
8596         { 0x0A,         "IOCTL2" },
8597         { 0x0B,         "FIND_NOTIFY_FIRST" },
8598         { 0x0C,         "FIND_NOTIFY_NEXT" },
8599         { 0x0D,         "CREATE_DIRECTORY" },
8600         { 0x0E,         "SESSION_SETUP" },
8601         { 0x10,         "GET_DFS_REFERRAL" },
8602         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
8603         { 0,    NULL }
8604 };
8605
8606 static const true_false_string tfs_tf_dtid = {
8607         "Also DISCONNECT TID",
8608         "Do NOT disconnect TID"
8609 };
8610 static const true_false_string tfs_tf_owt = {
8611         "One Way Transaction (NO RESPONSE)",
8612         "Two way transaction"
8613 };
8614
8615 static const true_false_string tfs_ff2_backup = {
8616         "Find WITH backup intent",
8617         "No backup intent"
8618 };
8619 static const true_false_string tfs_ff2_continue = {
8620         "CONTINUE search from previous position",
8621         "New search, do NOT continue from previous position"
8622 };
8623 static const true_false_string tfs_ff2_resume = {
8624         "Return RESUME keys",
8625         "Do NOT return resume keys"
8626 };
8627 static const true_false_string tfs_ff2_close_eos = {
8628         "CLOSE search if END OF SEARCH is reached",
8629         "Do NOT close search if end of search reached"
8630 };
8631 static const true_false_string tfs_ff2_close = {
8632         "CLOSE search after this request",
8633         "Do NOT close search after this request"
8634 };
8635
8636 /* used by
8637    TRANS2_FIND_FIRST2
8638 */
8639 static const value_string ff2_il_vals[] = {
8640         { 1,            "Info Standard  (4.3.4.1)"},
8641         { 2,            "Info Query EA Size  (4.3.4.2)"},
8642         { 3,            "Info Query EAs From List  (4.3.4.2)"},
8643         { 0x0101,       "Find File Directory Info  (4.3.4.4)"},
8644         { 0x0102,       "Find File Full Directory Info  (4.3.4.5)"},
8645         { 0x0103,       "Find File Names Info  (4.3.4.7)"},
8646         { 0x0104,       "Find File Both Directory Info  (4.3.4.6)"},
8647         { 0x0202,       "Find File UNIX  (4.3.4.8)"},
8648         {0, NULL}
8649 };
8650
8651 /* values used by :
8652         TRANS2_QUERY_PATH_INFORMATION
8653         TRANS2_SET_PATH_INFORMATION
8654 */
8655 static const value_string qpi_loi_vals[] = {
8656         { 1,            "Info Standard  (4.2.14.1)"},
8657         { 2,            "Info Query EA Size  (4.2.14.1)"},
8658         { 3,            "Info Query EAs From List  (4.2.14.2)"},
8659         { 4,            "Info Query All EAs  (4.2.14.2)"},
8660         { 6,            "Info Is Name Valid  (4.2.14.3)"},
8661         { 0x0101,       "Query File Basic Info  (4.2.14.4)"},
8662         { 0x0102,       "Query File Standard Info  (4.2.14.5)"},
8663         { 0x0103,       "Query File EA Info  (4.2.14.6)"},
8664         { 0x0104,       "Query File Name Info  (4.2.14.7)"},
8665         { 0x0107,       "Query File All Info  (4.2.14.8)"},
8666         { 0x0108,       "Query File Alt File Info  (4.2.14.7)"},
8667         { 0x0109,       "Query File Stream Info  (4.2.14.10)"},
8668         { 0x010b,       "Query File Compression Info  (4.2.14.11)"},
8669         { 0x0200,       "Set File Unix Basic"},
8670         { 0x0201,       "Set File Unix Link"},
8671         { 0x0202,       "Set File Unix HardLink"},
8672         {0, NULL}
8673 };
8674
8675 static const value_string qfsi_vals[] = {
8676         { 1,            "Info Allocation"},
8677         { 2,            "Info Volume"},
8678         { 0x0102,       "Query FS Volume Info"},
8679         { 0x0103,       "Query FS Size Info"},
8680         { 0x0104,       "Query FS Device Info"},
8681         { 0x0105,       "Query FS Attribute Info"},
8682         { 1006,         "Query FS Quota Info"},
8683         {0, NULL}
8684 };
8685
8686 static const value_string nt_rename_vals[] = {
8687         { 0x0103,       "Create Hard Link"},
8688         {0, NULL}
8689 };
8690
8691
8692 static const value_string delete_pending_vals[] = {
8693         {0,     "Normal, no pending delete"},
8694         {1,     "This object has DELETE PENDING"},
8695         {0, NULL}
8696 };
8697
8698 static const value_string alignment_vals[] = {
8699         {0,     "Byte alignment"},
8700         {1,     "Word (16bit) alignment"},
8701         {3,     "Long (32bit) alignment"},
8702         {7,     "8 byte boundary alignment"},
8703         {0x0f,  "16 byte boundary alignment"},
8704         {0x1f,  "32 byte boundary alignment"},
8705         {0x3f,  "64 byte boundary alignment"},
8706         {0x7f,  "128 byte boundary alignment"},
8707         {0xff,  "256 byte boundary alignment"},
8708         {0x1ff, "512 byte boundary alignment"},
8709         {0, NULL}
8710 };
8711
8712
8713 static const true_false_string tfs_get_dfs_server_hold_storage = {
8714         "Referral SERVER HOLDS STORAGE for the file",
8715         "Referral server does NOT hold storage for the file"
8716 };
8717 static const true_false_string tfs_get_dfs_fielding = {
8718         "The server in referral is FIELDING CAPABLE",
8719         "The server in referrals is NOT fielding capable"
8720 };
8721
8722 static const true_false_string tfs_dfs_referral_flags_strip = {
8723         "STRIP off pathconsumed characters before submitting",
8724         "Do NOT strip off any characters"
8725 };
8726
8727 static const value_string dfs_referral_server_type_vals[] = {
8728         {0,     "Don't know"},
8729         {1,     "SMB Server"},
8730         {2,     "Netware Server"},
8731         {3,     "Domain Server"},
8732         {0, NULL}
8733 };
8734
8735
8736 static const true_false_string tfs_device_char_removable = {
8737         "This is a REMOVABLE device",
8738         "This is NOT a removable device"
8739 };
8740 static const true_false_string tfs_device_char_read_only = {
8741         "This is a READ-ONLY device",
8742         "This is NOT a read-only device"
8743 };
8744 static const true_false_string tfs_device_char_floppy = {
8745         "This is a FLOPPY DISK device",
8746         "This is NOT a floppy disk device"
8747 };
8748 static const true_false_string tfs_device_char_write_once = {
8749         "This is a WRITE-ONCE device",
8750         "This is NOT a write-once device"
8751 };
8752 static const true_false_string tfs_device_char_remote = {
8753         "This is a REMOTE device",
8754         "This is NOT a remote device"
8755 };
8756 static const true_false_string tfs_device_char_mounted = {
8757         "This device is MOUNTED",
8758         "This device is NOT mounted"
8759 };
8760 static const true_false_string tfs_device_char_virtual = {
8761         "This is a VIRTUAL device",
8762         "This is NOT a virtual device"
8763 };
8764
8765
8766 static const true_false_string tfs_fs_attr_css = {
8767         "This FS supports CASE SENSITIVE SEARCHes",
8768         "This FS does NOT support case sensitive searches"
8769 };
8770 static const true_false_string tfs_fs_attr_cpn = {
8771         "This FS supports CASE PRESERVED NAMES",
8772         "This FS does NOT support case preserved names"
8773 };
8774 static const true_false_string tfs_fs_attr_pacls = {
8775         "This FS supports PERSISTENT ACLs",
8776         "This FS does NOT support persistent acls"
8777 };
8778 static const true_false_string tfs_fs_attr_fc = {
8779         "This FS supports COMPRESSED FILES",
8780         "This FS does NOT support compressed files"
8781 };
8782 static const true_false_string tfs_fs_attr_vq = {
8783         "This FS supports VOLUME QUOTAS",
8784         "This FS does NOT support volume quotas"
8785 };
8786 static const true_false_string tfs_fs_attr_dim = {
8787         "This FS is on a MOUNTED DEVICE",
8788         "This FS is NOT on a mounted device"
8789 };
8790 static const true_false_string tfs_fs_attr_vic = {
8791         "This FS is on a COMPRESSED VOLUME",
8792         "This FS is NOT on a compressed volume"
8793 };
8794
8795 #define FF2_RESUME      0x0004
8796
8797 static int
8798 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
8799 {
8800         guint16 mask;
8801         proto_item *item = NULL;
8802         proto_tree *tree = NULL;
8803         smb_info_t *si;
8804         smb_transact2_info_t *t2i;
8805
8806         mask = tvb_get_letohs(tvb, offset);
8807
8808         si = (smb_info_t *)pinfo->private_data;
8809         if (si->sip != NULL) {
8810                 t2i = si->sip->extra_info;
8811                 if (t2i != NULL) {
8812                         if (!pinfo->fd->flags.visited)
8813                                 t2i->resume_keys = (mask & FF2_RESUME);
8814                 }
8815         }
8816
8817         if(parent_tree){
8818                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
8819                         "Flags: 0x%04x", mask);
8820                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
8821         }
8822
8823         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
8824                 tvb, offset, 2, mask);
8825         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
8826                 tvb, offset, 2, mask);
8827         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
8828                 tvb, offset, 2, mask);
8829         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
8830                 tvb, offset, 2, mask);
8831         proto_tree_add_boolean(tree, hf_smb_ff2_close,
8832                 tvb, offset, 2, mask);
8833
8834         offset += 2;
8835
8836         return offset;
8837 }
8838
8839 static int
8840 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
8841     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
8842 {
8843         proto_item *item = NULL;
8844         proto_tree *tree = NULL;
8845         smb_info_t *si;
8846         smb_transact2_info_t *t2i;
8847         int fn_len;
8848         const char *fn;
8849         int old_offset = offset;
8850
8851         si = (smb_info_t *)pinfo->private_data;
8852         if (si->sip != NULL)
8853                 t2i = si->sip->extra_info;
8854         else
8855                 t2i = NULL;
8856
8857         if(parent_tree){
8858                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
8859                                 "%s Parameters",
8860                                 val_to_str(subcmd, trans2_cmd_vals, 
8861                                            "Unknown (0x%02x)"));
8862                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
8863         }
8864
8865         switch(subcmd){
8866         case 0x00:      /*TRANS2_OPEN2*/
8867                 /* open flags */
8868                 CHECK_BYTE_COUNT_TRANS(2);
8869                 offset = dissect_open_flags(tvb, pinfo, tree, offset, 0x000f);
8870                 bc -= 2;
8871
8872                 /* desired access */
8873                 CHECK_BYTE_COUNT_TRANS(2);
8874                 offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
8875                 bc -= 2;
8876
8877                 /* 2 reserved bytes */
8878                 CHECK_BYTE_COUNT_TRANS(2);
8879                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8880                 COUNT_BYTES_TRANS(2);
8881
8882                 /* File Attributes */
8883                 CHECK_BYTE_COUNT_TRANS(2);
8884                 offset = dissect_file_attributes(tvb, pinfo, tree, offset);
8885                 bc -= 2;
8886
8887                 /* create time */
8888                 CHECK_BYTE_COUNT_TRANS(4);
8889                 offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
8890                         hf_smb_create_time,
8891                         hf_smb_create_dos_date, hf_smb_create_dos_time,
8892                         TRUE);
8893                 bc -= 4;
8894
8895                 /* open function */
8896                 CHECK_BYTE_COUNT_TRANS(2);
8897                 offset = dissect_open_function(tvb, pinfo, tree, offset);
8898                 bc -= 2;
8899
8900                 /* allocation size */
8901                 CHECK_BYTE_COUNT_TRANS(4);
8902                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
8903                 COUNT_BYTES_TRANS(4);
8904
8905                 /* 10 reserved bytes */
8906                 CHECK_BYTE_COUNT_TRANS(10);
8907                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
8908                 COUNT_BYTES_TRANS(10);
8909
8910                 /* file name */
8911                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8912                 CHECK_STRING_TRANS(fn);
8913                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8914                         fn);
8915                 COUNT_BYTES_TRANS(fn_len);
8916
8917                 if (check_col(pinfo->cinfo, COL_INFO)) {
8918                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
8919                         fn);
8920                 }
8921
8922                 /* XXX dont know how to decode FEAList */
8923                 break;
8924         case 0x01:      /*TRANS2_FIND_FIRST2*/
8925                 /* Search Attributes */
8926                 CHECK_BYTE_COUNT_TRANS(2);
8927                 offset = dissect_search_attributes(tvb, pinfo, tree, offset);
8928                 bc -= 2;
8929
8930                 /* search count */
8931                 CHECK_BYTE_COUNT_TRANS(2);
8932                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
8933                 COUNT_BYTES_TRANS(2);
8934
8935                 /* Find First2 flags */
8936                 CHECK_BYTE_COUNT_TRANS(2);
8937                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
8938                 bc -= 2;
8939
8940                 /* Find First2 information level */
8941                 CHECK_BYTE_COUNT_TRANS(2);
8942                 si->info_level = tvb_get_letohs(tvb, offset);
8943                 if (!pinfo->fd->flags.visited)
8944                         t2i->info_level = si->info_level;
8945                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
8946                 COUNT_BYTES_TRANS(2);
8947
8948                 /* storage type */
8949                 CHECK_BYTE_COUNT_TRANS(4);
8950                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
8951                 COUNT_BYTES_TRANS(4);
8952
8953                 /* search pattern */
8954                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8955                 CHECK_STRING_TRANS(fn);
8956                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
8957                         fn);
8958                 COUNT_BYTES_TRANS(fn_len);
8959
8960                 if (check_col(pinfo->cinfo, COL_INFO)) {
8961                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
8962                         fn);
8963                 }
8964
8965                 /* XXX dont know how to decode FEAList */
8966
8967                 break;
8968         case 0x02:      /*TRANS2_FIND_NEXT2*/
8969                 /* sid */
8970                 CHECK_BYTE_COUNT_TRANS(2);
8971                 proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
8972                 COUNT_BYTES_TRANS(2);
8973
8974                 /* search count */
8975                 CHECK_BYTE_COUNT_TRANS(2);
8976                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
8977                 COUNT_BYTES_TRANS(2);
8978
8979                 /* Find First2 information level */
8980                 CHECK_BYTE_COUNT_TRANS(2);
8981                 si->info_level = tvb_get_letohs(tvb, offset);
8982                 if (!pinfo->fd->flags.visited)
8983                         t2i->info_level = si->info_level;
8984                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
8985                 COUNT_BYTES_TRANS(2);
8986
8987                 /* resume key */
8988                 CHECK_BYTE_COUNT_TRANS(4);
8989                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
8990                 COUNT_BYTES_TRANS(4);
8991
8992                 /* Find First2 flags */
8993                 CHECK_BYTE_COUNT_TRANS(2);
8994                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
8995                 bc -= 2;
8996
8997                 /* file name */
8998                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8999                 CHECK_STRING_TRANS(fn);
9000                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9001                         fn);
9002                 COUNT_BYTES_TRANS(fn_len);
9003
9004                 if (check_col(pinfo->cinfo, COL_INFO)) {
9005                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
9006                         fn);
9007                 }
9008
9009                 break;
9010         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
9011                 /* level of interest */
9012                 CHECK_BYTE_COUNT_TRANS(2);
9013                 si->info_level = tvb_get_letohs(tvb, offset);
9014                 if (!pinfo->fd->flags.visited)
9015                         t2i->info_level = si->info_level;
9016                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
9017                 COUNT_BYTES_TRANS(2);
9018
9019                 break;
9020         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
9021                 /* level of interest */
9022                 CHECK_BYTE_COUNT_TRANS(2);
9023                 si->info_level = tvb_get_letohs(tvb, offset);
9024                 if (!pinfo->fd->flags.visited)
9025                         t2i->info_level = si->info_level;
9026                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9027                 COUNT_BYTES_TRANS(2);
9028                 
9029                 /* 4 reserved bytes */
9030                 CHECK_BYTE_COUNT_TRANS(4);
9031                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9032                 COUNT_BYTES_TRANS(4);
9033
9034                 /* file name */
9035                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9036                 CHECK_STRING_TRANS(fn);
9037                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9038                         fn);
9039                 COUNT_BYTES_TRANS(fn_len);
9040
9041                 if (check_col(pinfo->cinfo, COL_INFO)) {
9042                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9043                         fn);
9044                 }
9045
9046                 break;
9047         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
9048                 /* level of interest */
9049                 CHECK_BYTE_COUNT_TRANS(2);
9050                 si->info_level = tvb_get_letohs(tvb, offset);
9051                 if (!pinfo->fd->flags.visited)
9052                         t2i->info_level = si->info_level;
9053                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9054                 COUNT_BYTES_TRANS(2);
9055                 
9056                 /* 4 reserved bytes */
9057                 CHECK_BYTE_COUNT_TRANS(4);
9058                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9059                 COUNT_BYTES_TRANS(4);
9060
9061                 /* file name */
9062                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9063                 CHECK_STRING_TRANS(fn);
9064                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9065                         fn);
9066                 COUNT_BYTES_TRANS(fn_len);
9067
9068                 if (check_col(pinfo->cinfo, COL_INFO)) {
9069                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
9070                         fn);
9071                 }
9072
9073                 break;
9074         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
9075                 guint16 fid;
9076
9077                 /* fid */
9078                 CHECK_BYTE_COUNT_TRANS(2);
9079                 fid = tvb_get_letohs(tvb, offset);
9080                 add_fid(tvb, pinfo, tree, offset, 2, fid);
9081                 COUNT_BYTES_TRANS(2);
9082
9083                 /* level of interest */
9084                 CHECK_BYTE_COUNT_TRANS(2);
9085                 si->info_level = tvb_get_letohs(tvb, offset);
9086                 if (!pinfo->fd->flags.visited)
9087                         t2i->info_level = si->info_level;
9088                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9089                 COUNT_BYTES_TRANS(2);
9090                 
9091                 break;
9092         }
9093         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
9094                 guint16 fid;
9095
9096                 /* fid */
9097                 CHECK_BYTE_COUNT_TRANS(2);
9098                 fid = tvb_get_letohs(tvb, offset);
9099                 add_fid(tvb, pinfo, tree, offset, 2, fid);
9100                 COUNT_BYTES_TRANS(2);
9101
9102                 /* level of interest */
9103                 CHECK_BYTE_COUNT_TRANS(2);
9104                 si->info_level = tvb_get_letohs(tvb, offset);
9105                 if (!pinfo->fd->flags.visited)
9106                         t2i->info_level = si->info_level;
9107                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
9108                 COUNT_BYTES_TRANS(2);
9109                 
9110                 /* 2 reserved bytes */
9111                 CHECK_BYTE_COUNT_TRANS(2);
9112                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
9113                 COUNT_BYTES_TRANS(2);
9114
9115                 break;
9116         }
9117         case 0x09:      /*TRANS2_FSCTL*/
9118         case 0x0a:      /*TRANS2_IOCTL2*/
9119                 /* these calls have no parameter block in the request */
9120                 break;
9121         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
9122         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
9123                 /* XXX unknown structure*/
9124                 break;
9125         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
9126                 /* 4 reserved bytes */
9127                 CHECK_BYTE_COUNT_TRANS(4);
9128                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
9129                 COUNT_BYTES_TRANS(4);
9130
9131                 /* dir name */
9132                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
9133                         FALSE, FALSE, &bc);
9134                 CHECK_STRING_TRANS(fn);
9135                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
9136                         fn);
9137                 COUNT_BYTES_TRANS(fn_len);
9138
9139                 if (check_col(pinfo->cinfo, COL_INFO)) {
9140                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
9141                         fn);
9142                 }
9143
9144                 /* XXX optional FEAList, unknown what FEAList looks like*/
9145                 break;
9146         case 0x0e:      /*TRANS2_SESSION_SETUP*/
9147                 /* XXX unknown structure*/
9148                 break;
9149         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
9150                 /* referral level */
9151                 CHECK_BYTE_COUNT_TRANS(2);
9152                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
9153                 COUNT_BYTES_TRANS(2);
9154                 
9155                 /* file name */
9156                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9157                 CHECK_STRING_TRANS(fn);
9158                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9159                         fn);
9160                 COUNT_BYTES_TRANS(fn_len);
9161
9162                 if (check_col(pinfo->cinfo, COL_INFO)) {
9163                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
9164                         fn);
9165                 }
9166
9167                 break;
9168         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
9169                 /* file name */
9170                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
9171                 CHECK_STRING_TRANS(fn);
9172                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9173                         fn);
9174                 COUNT_BYTES_TRANS(fn_len);
9175
9176                 if (check_col(pinfo->cinfo, COL_INFO)) {
9177                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
9178                         fn);
9179                 }
9180
9181                 break;
9182         }
9183
9184         /* ooops there were data we didnt know how to process */
9185         if((offset-old_offset) < bc){
9186                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
9187                     bc - (offset-old_offset), TRUE);
9188                 offset += bc - (offset-old_offset);
9189         }
9190
9191         return offset;
9192 }
9193
9194 /*
9195  * XXX - just use "dissect_connect_flags()" here?
9196  */
9197 static guint16
9198 dissect_transaction_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9199 {
9200         guint16 mask;
9201         proto_item *item = NULL;
9202         proto_tree *tree = NULL;
9203
9204         mask = tvb_get_letohs(tvb, offset);
9205
9206         if(parent_tree){
9207                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9208                         "Flags: 0x%04x", mask);
9209                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
9210         }
9211
9212         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
9213                 tvb, offset, 2, mask);
9214         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
9215                 tvb, offset, 2, mask);
9216
9217         return mask;
9218 }
9219  
9220
9221 static int
9222 dissect_get_dfs_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9223 {
9224         guint16 mask;
9225         proto_item *item = NULL;
9226         proto_tree *tree = NULL;
9227
9228         mask = tvb_get_letohs(tvb, offset);
9229
9230         if(parent_tree){
9231                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9232                         "Flags: 0x%04x", mask);
9233                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
9234         }
9235
9236         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
9237                 tvb, offset, 2, mask);
9238         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
9239                 tvb, offset, 2, mask);
9240
9241         offset += 2;
9242         return offset;
9243 }
9244
9245 static int
9246 dissect_dfs_referral_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9247 {
9248         guint16 mask;
9249         proto_item *item = NULL;
9250         proto_tree *tree = NULL;
9251
9252         mask = tvb_get_letohs(tvb, offset);
9253
9254         if(parent_tree){
9255                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9256                         "Flags: 0x%04x", mask);
9257                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
9258         }
9259
9260         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
9261                 tvb, offset, 2, mask);
9262
9263         offset += 2;
9264
9265         return offset;
9266 }
9267
9268
9269 /* dfs inconsistency data  (4.4.2)
9270 */
9271 static int
9272 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
9273     proto_tree *tree, int offset, guint16 *bcp)
9274 {
9275         int fn_len;
9276         const char *fn;
9277
9278         /*XXX shouldn this data hold version and size? unclear from doc*/
9279         /* referral version */
9280         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9281         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
9282         COUNT_BYTES_TRANS_SUBR(2);
9283
9284         /* referral size */
9285         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9286         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
9287         COUNT_BYTES_TRANS_SUBR(2);
9288
9289         /* referral server type */
9290         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9291         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
9292         COUNT_BYTES_TRANS_SUBR(2);
9293
9294         /* referral flags */
9295         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9296         offset = dissect_dfs_referral_flags(tvb, pinfo, tree, offset);
9297         *bcp -= 2;
9298
9299         /* node name */
9300         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9301         CHECK_STRING_TRANS_SUBR(fn);
9302         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
9303                 fn);
9304         COUNT_BYTES_TRANS_SUBR(fn_len);
9305
9306         return offset;
9307 }
9308
9309 /* get dfs referral data  (4.4.1)
9310 */
9311 static int
9312 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
9313     proto_tree *tree, int offset, guint16 *bcp)
9314 {
9315         guint16 numref;
9316         guint16 refsize;
9317         guint16 pathoffset;
9318         guint16 altpathoffset;
9319         guint16 nodeoffset;
9320         int fn_len;
9321         int stroffset;
9322         int offsetoffset;
9323         guint16 save_bc;
9324         const char *fn;
9325         int unklen;
9326         int ucstring_end;
9327         int ucstring_len;
9328
9329         /* path consumed */
9330         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9331         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
9332         COUNT_BYTES_TRANS_SUBR(2);
9333
9334         /* num referrals */
9335         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9336         numref = tvb_get_letohs(tvb, offset);
9337         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
9338         COUNT_BYTES_TRANS_SUBR(2);
9339
9340         /* get dfs flags */
9341         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9342         offset = dissect_get_dfs_flags(tvb, pinfo, tree, offset);
9343         *bcp -= 2;
9344
9345         /* XXX - in at least one capture there appears to be 2 bytes
9346            of stuff after the Dfs flags, perhaps so that the header
9347            in front of the referral list is a multiple of 4 bytes long. */
9348         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9349         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
9350         COUNT_BYTES_TRANS_SUBR(2);
9351
9352         /* if there are any referrals */
9353         if(numref){
9354                 proto_item *ref_item = NULL;
9355                 proto_tree *ref_tree = NULL;
9356                 int old_offset=offset;
9357
9358                 if(tree){
9359                         ref_item = proto_tree_add_text(tree,
9360                                 tvb, offset, *bcp, "Referrals");
9361                         ref_tree = proto_item_add_subtree(ref_item,
9362                                 ett_smb_dfs_referrals);
9363                 }
9364                 ucstring_end = -1;
9365
9366                 while(numref--){
9367                         proto_item *ri = NULL;
9368                         proto_tree *rt = NULL;
9369                         int old_offset=offset;
9370                         guint16 version;
9371
9372                         if(tree){
9373                                 ri = proto_tree_add_text(ref_tree,
9374                                         tvb, offset, *bcp, "Referral");
9375                                 rt = proto_item_add_subtree(ri,
9376                                         ett_smb_dfs_referral);
9377                         }
9378                 
9379                         /* referral version */
9380                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9381                         version = tvb_get_letohs(tvb, offset);
9382                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
9383                                 tvb, offset, 2, version);
9384                         COUNT_BYTES_TRANS_SUBR(2);
9385
9386                         /* referral size */
9387                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9388                         refsize = tvb_get_letohs(tvb, offset);
9389                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
9390                         COUNT_BYTES_TRANS_SUBR(2);
9391
9392                         /* referral server type */
9393                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9394                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
9395                         COUNT_BYTES_TRANS_SUBR(2);
9396
9397                         /* referral flags */
9398                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
9399                         offset = dissect_dfs_referral_flags(tvb, pinfo, rt, offset);
9400                         *bcp -= 2;
9401
9402                         switch(version){
9403
9404                         case 1:
9405                                 /* node name */
9406                                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9407                                 CHECK_STRING_TRANS_SUBR(fn);
9408                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
9409                                         fn);
9410                                 COUNT_BYTES_TRANS_SUBR(fn_len);
9411                                 break;
9412
9413                         case 2:
9414                         case 3: /* XXX - like version 2, but not identical;
9415                                    seen in a capture, but the format isn't
9416                                    documented */
9417                                 /* proximity */
9418                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9419                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
9420                                 COUNT_BYTES_TRANS_SUBR(2);
9421
9422                                 /* ttl */
9423                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9424                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
9425                                 COUNT_BYTES_TRANS_SUBR(2);
9426
9427                                 /* path offset */
9428                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9429                                 pathoffset = tvb_get_letohs(tvb, offset);
9430                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
9431                                 COUNT_BYTES_TRANS_SUBR(2);
9432
9433                                 /* alt path offset */
9434                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9435                                 altpathoffset = tvb_get_letohs(tvb, offset);
9436                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
9437                                 COUNT_BYTES_TRANS_SUBR(2);
9438
9439                                 /* node offset */
9440                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9441                                 nodeoffset = tvb_get_letohs(tvb, offset);
9442                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
9443                                 COUNT_BYTES_TRANS_SUBR(2);
9444
9445                                 /* path */
9446                                 if (pathoffset != 0) {
9447                                         stroffset = old_offset + pathoffset;
9448                                         offsetoffset = stroffset - offset;
9449                                         if (offsetoffset > 0 &&
9450                                             *bcp > offsetoffset) {
9451                                                 save_bc = *bcp;
9452                                                 *bcp -= offsetoffset;
9453                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
9454                                                 CHECK_STRING_TRANS_SUBR(fn);
9455                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
9456                                                         fn);
9457                                                 stroffset += fn_len;
9458                                                 if (ucstring_end < stroffset)
9459                                                         ucstring_end = stroffset;
9460                                                 *bcp = save_bc;
9461                                         }
9462                                 }
9463                         
9464                                 /* alt path */
9465                                 if (altpathoffset != 0) {
9466                                         stroffset = old_offset + altpathoffset;
9467                                         offsetoffset = stroffset - offset;
9468                                         if (offsetoffset > 0 &&
9469                                             *bcp > offsetoffset) {
9470                                                 save_bc = *bcp;
9471                                                 *bcp -= offsetoffset;
9472                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
9473                                                 CHECK_STRING_TRANS_SUBR(fn);
9474                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
9475                                                         fn);
9476                                                 stroffset += fn_len;
9477                                                 if (ucstring_end < stroffset)
9478                                                         ucstring_end = stroffset;
9479                                                 *bcp = save_bc;
9480                                         }
9481                                 }
9482                         
9483                                 /* node */
9484                                 if (nodeoffset != 0) {
9485                                         stroffset = old_offset + nodeoffset;
9486                                         offsetoffset = stroffset - offset;
9487                                         if (offsetoffset > 0 &&
9488                                             *bcp > offsetoffset) {
9489                                                 save_bc = *bcp;
9490                                                 *bcp -= offsetoffset;
9491                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
9492                                                 CHECK_STRING_TRANS_SUBR(fn);
9493                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
9494                                                         fn);
9495                                                 stroffset += fn_len;
9496                                                 if (ucstring_end < stroffset)
9497                                                         ucstring_end = stroffset;
9498                                                 *bcp = save_bc;
9499                                         }
9500                                 }
9501                                 break;
9502                         }
9503
9504                         /*
9505                          * Show anything beyond the length of the referral
9506                          * as unknown data.
9507                          */
9508                         unklen = (old_offset + refsize) - offset;
9509                         if (unklen < 0) {
9510                                 /*
9511                                  * XXX - the length is bogus.
9512                                  */
9513                                 unklen = 0;
9514                         }
9515                         if (unklen != 0) {
9516                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
9517                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
9518                                     offset, unklen, TRUE);
9519                                 COUNT_BYTES_TRANS_SUBR(unklen);
9520                         }
9521
9522                         proto_item_set_len(ri, offset-old_offset);
9523                 }
9524
9525                 /*
9526                  * Treat the offset past the end of the last Unicode
9527                  * string after the referrals (if any) as the last
9528                  * offset.
9529                  */
9530                 if (ucstring_end > offset) {
9531                         ucstring_len = ucstring_end - offset;
9532                         if (*bcp < ucstring_len)
9533                                 ucstring_len = *bcp;
9534                         offset += ucstring_len;
9535                         *bcp -= ucstring_len;
9536                 }
9537                 proto_item_set_len(ref_item, offset-old_offset);
9538         }
9539
9540         return offset;
9541 }
9542
9543
9544 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
9545    as described in 4.2.14.1
9546 */
9547 static int
9548 dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9549     int offset, guint16 *bcp, gboolean *trunc)
9550 {
9551         /* create time */
9552         CHECK_BYTE_COUNT_SUBR(4);
9553         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9554                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
9555                 FALSE);
9556         *bcp -= 4;
9557
9558         /* access time */
9559         CHECK_BYTE_COUNT_SUBR(4);
9560         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9561                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
9562                 FALSE);
9563         *bcp -= 4;
9564
9565         /* last write time */
9566         CHECK_BYTE_COUNT_SUBR(4);
9567         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9568                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
9569                 FALSE);
9570         *bcp -= 4;
9571
9572         /* data size */
9573         CHECK_BYTE_COUNT_SUBR(4);
9574         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
9575         COUNT_BYTES_SUBR(4);
9576
9577         /* allocation size */
9578         CHECK_BYTE_COUNT_SUBR(4);
9579         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
9580         COUNT_BYTES_SUBR(4);
9581
9582         /* File Attributes */
9583         CHECK_BYTE_COUNT_SUBR(2);
9584         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
9585         *bcp -= 2;
9586
9587         /* ea size */
9588         CHECK_BYTE_COUNT_SUBR(4);
9589         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
9590         COUNT_BYTES_SUBR(4);
9591
9592         *trunc = FALSE;
9593         return offset;
9594 }
9595
9596 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
9597    as described in 4.2.14.2
9598 */
9599 static int
9600 dissect_4_2_14_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9601     int offset, guint16 *bcp, gboolean *trunc)
9602 {
9603         /* list length */
9604         CHECK_BYTE_COUNT_SUBR(4);
9605         proto_tree_add_item(tree, hf_smb_list_length, tvb, offset, 4, TRUE);
9606         COUNT_BYTES_SUBR(4);
9607
9608         *trunc = FALSE;
9609         return offset;
9610 }
9611
9612 /* this dissects the SMB_INFO_IS_NAME_VALID
9613    as described in 4.2.14.3
9614 */
9615 static int
9616 dissect_4_2_14_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9617     int offset, guint16 *bcp, gboolean *trunc)
9618 {
9619         int fn_len;
9620         const char *fn;
9621
9622         /* file name */
9623         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9624         CHECK_STRING_SUBR(fn);
9625         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9626                 fn);
9627         COUNT_BYTES_SUBR(fn_len);
9628
9629         *trunc = FALSE;
9630         return offset;
9631 }
9632
9633 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
9634    as described in 4.2.14.4
9635 */
9636 static int
9637 dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9638     int offset, guint16 *bcp, gboolean *trunc)
9639 {
9640         /* create time */
9641         CHECK_BYTE_COUNT_SUBR(8);
9642         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9643                 hf_smb_create_time);
9644         *bcp -= 8;
9645         
9646         /* access time */
9647         CHECK_BYTE_COUNT_SUBR(8);
9648         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9649                 hf_smb_access_time);
9650         *bcp -= 8;
9651         
9652         /* last write time */
9653         CHECK_BYTE_COUNT_SUBR(8);
9654         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9655                 hf_smb_last_write_time);
9656         *bcp -= 8;
9657         
9658         /* last change time */
9659         CHECK_BYTE_COUNT_SUBR(8);
9660         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9661                 hf_smb_change_time);
9662         *bcp -= 8;
9663         
9664         /* File Attributes */
9665         CHECK_BYTE_COUNT_SUBR(2);
9666         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
9667         *bcp -= 2;
9668
9669         *trunc = FALSE;
9670         return offset;
9671 }
9672
9673 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
9674    as described in 4.2.14.5
9675 */
9676 static int
9677 dissect_4_2_14_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9678     int offset, guint16 *bcp, gboolean *trunc)
9679 {
9680         /* allocation size */
9681         CHECK_BYTE_COUNT_SUBR(8);
9682         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9683         COUNT_BYTES_SUBR(8);
9684
9685         /* end of file */
9686         CHECK_BYTE_COUNT_SUBR(8);
9687         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9688         COUNT_BYTES_SUBR(8);
9689
9690         /* number of links */
9691         CHECK_BYTE_COUNT_SUBR(4);
9692         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
9693         COUNT_BYTES_SUBR(4);
9694
9695         /* delete pending */
9696         CHECK_BYTE_COUNT_SUBR(2);
9697         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 2, TRUE);
9698         COUNT_BYTES_SUBR(2);
9699
9700         /* is directory */
9701         CHECK_BYTE_COUNT_SUBR(1);
9702         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9703         COUNT_BYTES_SUBR(1);
9704
9705         *trunc = FALSE;
9706         return offset;
9707 }
9708
9709 /* this dissects the SMB_QUERY_FILE_EA_INFO
9710    as described in 4.2.14.6
9711 */
9712 static int
9713 dissect_4_2_14_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9714     int offset, guint16 *bcp, gboolean *trunc)
9715 {
9716         /* ea size */
9717         CHECK_BYTE_COUNT_SUBR(4);
9718         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
9719         COUNT_BYTES_SUBR(4);
9720
9721         *trunc = FALSE;
9722         return offset;
9723 }
9724
9725 /* this dissects the SMB_QUERY_FILE_NAME_INFO
9726    as described in 4.2.14.7
9727    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
9728    as described in 4.2.14.9
9729 */
9730 static int
9731 dissect_4_2_14_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9732     int offset, guint16 *bcp, gboolean *trunc)
9733 {
9734         int fn_len;
9735         const char *fn;
9736
9737         /* file name len */
9738         CHECK_BYTE_COUNT_SUBR(4);
9739         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
9740         COUNT_BYTES_SUBR(4);
9741
9742         /* file name */
9743         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9744         CHECK_STRING_SUBR(fn);
9745         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9746                 fn);
9747         COUNT_BYTES_SUBR(fn_len);
9748
9749         *trunc = FALSE;
9750         return offset;
9751 }
9752
9753 /* this dissects the SMB_QUERY_FILE_ALL_INFO
9754    as described in 4.2.14.8
9755 */
9756 static int
9757 dissect_4_2_14_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9758     int offset, guint16 *bcp, gboolean *trunc)
9759 {
9760
9761         offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp, trunc);
9762         if (trunc)
9763                 return offset;
9764         offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp, trunc);
9765         if (trunc)
9766                 return offset;
9767
9768         /* index number */
9769         CHECK_BYTE_COUNT_SUBR(8);
9770         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
9771         COUNT_BYTES_SUBR(8);
9772
9773         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
9774         if (trunc)
9775                 return offset;
9776
9777         /* access flags */
9778         CHECK_BYTE_COUNT_SUBR(4);
9779         offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
9780         COUNT_BYTES_SUBR(4);
9781
9782         /* index number */
9783         CHECK_BYTE_COUNT_SUBR(8);
9784         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
9785         COUNT_BYTES_SUBR(8);
9786
9787         /* current offset */
9788         CHECK_BYTE_COUNT_SUBR(8);
9789         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
9790         COUNT_BYTES_SUBR(8);
9791
9792         /* mode */
9793         CHECK_BYTE_COUNT_SUBR(4);
9794         offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
9795         *bcp -= 4;
9796
9797         /* alignment */
9798         CHECK_BYTE_COUNT_SUBR(4);
9799         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
9800         COUNT_BYTES_SUBR(4);
9801         
9802         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
9803
9804         return offset;
9805 }
9806
9807 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
9808    as described in 4.2.14.10
9809 */
9810 static int
9811 dissect_4_2_14_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
9812     int offset, guint16 *bcp, gboolean *trunc)
9813 {
9814         proto_item *item;
9815         proto_tree *tree;
9816         int old_offset;
9817         guint32 neo;
9818         int fn_len;
9819         const char *fn;
9820         int padcnt;
9821
9822         for (;;) {
9823                 old_offset = offset;
9824
9825                 /* next entry offset */
9826                 CHECK_BYTE_COUNT_SUBR(4);
9827                 if(parent_tree){
9828                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
9829                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
9830                 } else {
9831                         item = NULL;
9832                         tree = NULL;
9833                 }
9834
9835                 neo = tvb_get_letohl(tvb, offset);
9836                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
9837                 COUNT_BYTES_SUBR(4);
9838         
9839                 /* stream name len */
9840                 CHECK_BYTE_COUNT_SUBR(4);
9841                 fn_len = tvb_get_letohl(tvb, offset);
9842                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
9843                 COUNT_BYTES_SUBR(4);
9844         
9845                 /* stream size */
9846                 CHECK_BYTE_COUNT_SUBR(8);
9847                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
9848                 COUNT_BYTES_SUBR(8);
9849
9850                 /* allocation size */
9851                 CHECK_BYTE_COUNT_SUBR(8);
9852                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9853                 COUNT_BYTES_SUBR(8);
9854
9855                 /* stream name */
9856                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
9857                 CHECK_STRING_SUBR(fn);
9858                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
9859                         fn);
9860                 COUNT_BYTES_SUBR(fn_len);
9861  
9862                 proto_item_append_text(item, ": %s", fn);
9863                 proto_item_set_len(item, offset-old_offset);
9864
9865                 if (neo == 0)
9866                         break;  /* no more structures */
9867
9868                 /* skip to next structure */
9869                 padcnt = (old_offset + neo) - offset;
9870                 if (padcnt < 0) {
9871                         /*
9872                          * XXX - this is bogus; flag it?
9873                          */
9874                         padcnt = 0;
9875                 }
9876                 if (padcnt != 0) {
9877                         CHECK_BYTE_COUNT_SUBR(padcnt);
9878                         COUNT_BYTES_SUBR(padcnt);
9879                 }
9880         }
9881
9882         *trunc = FALSE;
9883         return offset;
9884 }
9885
9886 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
9887    as described in 4.2.14.11
9888 */
9889 static int
9890 dissect_4_2_14_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9891     int offset, guint16 *bcp, gboolean *trunc)
9892 {
9893         /* compressed file size */
9894         CHECK_BYTE_COUNT_SUBR(8);
9895         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
9896         COUNT_BYTES_SUBR(8);
9897
9898         /* compression format */
9899         CHECK_BYTE_COUNT_SUBR(2);
9900         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
9901         COUNT_BYTES_SUBR(2);
9902         
9903         /* compression unit shift */
9904         CHECK_BYTE_COUNT_SUBR(1);
9905         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
9906         COUNT_BYTES_SUBR(1);
9907         
9908         /* compression chunk shift */
9909         CHECK_BYTE_COUNT_SUBR(1);
9910         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
9911         COUNT_BYTES_SUBR(1);
9912         
9913         /* compression cluster shift */
9914         CHECK_BYTE_COUNT_SUBR(1);
9915         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
9916         COUNT_BYTES_SUBR(1);
9917         
9918         /* 3 reserved bytes */
9919         CHECK_BYTE_COUNT_SUBR(3);
9920         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
9921         COUNT_BYTES_SUBR(3);
9922
9923         *trunc = FALSE;
9924         return offset;
9925 }
9926
9927
9928
9929 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION*/
9930 static int
9931 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
9932     int offset, guint16 *bcp)
9933 {
9934         smb_info_t *si;
9935         gboolean trunc;
9936
9937         if(!*bcp){
9938                 return offset;
9939         }
9940         
9941         si = (smb_info_t *)pinfo->private_data;
9942         switch(si->info_level){
9943         case 1:         /*Info Standard*/
9944         case 2:         /*Info Query EA Size*/
9945                 offset = dissect_4_2_14_1(tvb, pinfo, tree, offset, bcp,
9946                     &trunc);
9947                 break;
9948         case 3:         /*Info Query EAs From List*/
9949         case 4:         /*Info Query All EAs*/
9950                 offset = dissect_4_2_14_2(tvb, pinfo, tree, offset, bcp,
9951                     &trunc);
9952                 break;
9953         case 6:         /*Info Is Name Valid*/
9954                 offset = dissect_4_2_14_3(tvb, pinfo, tree, offset, bcp,
9955                     &trunc);
9956                 break;
9957         case 0x0101:    /*Query File Basic Info*/
9958                 offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp,
9959                     &trunc);
9960                 break;
9961         case 0x0102:    /*Query File Standard Info*/
9962                 offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp,
9963                     &trunc);
9964                 break;
9965         case 0x0103:    /*Query File EA Info*/
9966                 offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp,
9967                     &trunc);
9968                 break;
9969         case 0x0104:    /*Query File Name Info*/
9970                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
9971                     &trunc);
9972                 break;
9973         case 0x0107:    /*Query File All Info*/
9974                 offset = dissect_4_2_14_8(tvb, pinfo, tree, offset, bcp,
9975                     &trunc);
9976                 break;
9977         case 0x0108:    /*Query File Alt File Info*/
9978                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
9979                     &trunc);
9980                 break;
9981         case 0x0109:    /*Query File Stream Info*/
9982                 offset = dissect_4_2_14_10(tvb, pinfo, tree, offset, bcp,
9983                     &trunc);
9984                 break;
9985         case 0x010b:    /*Query File Compression Info*/
9986                 offset = dissect_4_2_14_11(tvb, pinfo, tree, offset, bcp,
9987                     &trunc);
9988                 break;
9989         case 0x0200:    /*Set File Unix Basic*/
9990                 /* XXX add this from the SNIA doc */
9991                 break;
9992         case 0x0201:    /*Set File Unix Link*/
9993                 /* XXX add this from the SNIA doc */
9994                 break;
9995         case 0x0202:    /*Set File Unix HardLink*/
9996                 /* XXX add this from the SNIA doc */
9997                 break;
9998         }
9999         
10000         return offset;
10001 }
10002
10003
10004 static const true_false_string tfs_quota_flags_deny_disk = {
10005         "DENY DISK SPACE for users exceeding quota limit",
10006         "Do NOT deny disk space for users exceeding quota limit"
10007 };
10008 static const true_false_string tfs_quota_flags_log_limit = {
10009         "LOG EVENT when a user exceeds their QUOTA LIMIT",
10010         "Do NOT log event when a user exceeds their quota limit"
10011 };
10012 static const true_false_string tfs_quota_flags_log_warning = {
10013         "LOG EVENT when a user exceeds their WARNING LEVEL",
10014         "Do NOT log event when a user exceeds their warning level"
10015 };
10016 static const true_false_string tfs_quota_flags_enabled = {
10017         "Quotas are ENABLED of this fs",
10018         "Quotas are NOT enabled on this fs"
10019 };
10020 static void
10021 dissect_quota_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
10022 {
10023         guint8 mask;
10024         proto_item *item = NULL;
10025         proto_tree *tree = NULL;
10026
10027         mask = tvb_get_guint8(tvb, offset);
10028
10029         if(parent_tree){
10030                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
10031                         "Quota Flags: 0x%02x %s", mask,
10032                         mask?"Enabled":"Disabled");
10033                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
10034         }
10035
10036         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
10037                 tvb, offset, 1, mask);
10038         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
10039                 tvb, offset, 1, mask);
10040         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
10041                 tvb, offset, 1, mask);
10042
10043         if(mask && (!(mask&0x01))){
10044                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
10045                         tvb, offset, 1, 0x01);
10046         } else {
10047                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
10048                         tvb, offset, 1, mask);
10049         }
10050
10051 }
10052
10053 static int
10054 dissect_nt_quota(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 *bcp)
10055 {
10056         /* first 24 bytes are unknown */
10057         CHECK_BYTE_COUNT_TRANS_SUBR(24);
10058         proto_tree_add_item(tree, hf_smb_unknown, tvb,
10059                     offset, 24, TRUE);
10060         COUNT_BYTES_TRANS_SUBR(24);
10061
10062         /* number of bytes for quota warning */
10063         CHECK_BYTE_COUNT_TRANS_SUBR(8);
10064         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
10065         COUNT_BYTES_TRANS_SUBR(8);
10066
10067         /* number of bytes for quota limit */
10068         CHECK_BYTE_COUNT_TRANS_SUBR(8);
10069         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
10070         COUNT_BYTES_TRANS_SUBR(8);
10071
10072         /* one byte of quota flags */
10073         CHECK_BYTE_COUNT_TRANS_SUBR(1);
10074         dissect_quota_flags(tvb, pinfo, tree, offset);
10075         COUNT_BYTES_TRANS_SUBR(1);
10076
10077         /* these 7 bytes are unknown */
10078         CHECK_BYTE_COUNT_TRANS_SUBR(7);
10079         proto_tree_add_item(tree, hf_smb_unknown, tvb,
10080                     offset, 7, TRUE);
10081         COUNT_BYTES_TRANS_SUBR(7);
10082
10083         return offset;
10084 }
10085
10086 static int
10087 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
10088     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
10089 {
10090         proto_item *item = NULL;
10091         proto_tree *tree = NULL;
10092         smb_info_t *si;
10093
10094         si = (smb_info_t *)pinfo->private_data;
10095
10096         if(parent_tree){
10097                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
10098                                 "%s Data",
10099                                 val_to_str(subcmd, trans2_cmd_vals, 
10100                                                 "Unknown (0x%02x)"));
10101                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
10102         }
10103
10104         switch(subcmd){
10105         case 0x00:      /*TRANS2_OPEN2*/
10106                 /* XXX FAEList here?*/
10107                 break;
10108         case 0x01:      /*TRANS2_FIND_FIRST2*/
10109                 /* XXX FAEList here?*/
10110                 break;
10111         case 0x02:      /*TRANS2_FIND_NEXT2*/
10112                 /* no data field in this request */
10113                 break;
10114         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10115                 /* no data field in this request */
10116                 break;
10117         case 0x04:      /* TRANS2_SET_QUOTA */
10118                 offset = dissect_nt_quota(tvb, pinfo, tree, offset, &dc);
10119                 break;
10120         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10121                 /* no data field in this request */
10122                 break;
10123         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10124                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
10125                 break;
10126         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
10127                 /* no data field in this request */
10128                 break;
10129         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
10130                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
10131                 break;
10132         case 0x09:      /*TRANS2_FSCTL*/
10133                 /*XXX dont know how to decode this yet */
10134                 break;
10135         case 0x0a:      /*TRANS2_IOCTL2*/
10136                 /*XXX dont know how to decode this yet */
10137                 break;
10138         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
10139                 /*XXX dont know how to decode this yet */
10140                 break;
10141         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
10142                 /*XXX dont know how to decode this yet */
10143                 break;
10144         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10145                 /* no data block for this one */
10146                 break;
10147         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10148                 /*XXX dont know how to decode this yet */
10149                 break;
10150         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10151                 /* no data field in this request */
10152                 break;
10153         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10154                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
10155                 break;
10156         }
10157
10158         /* ooops there were data we didnt know how to process */
10159         if(dc != 0){
10160                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
10161                 offset += dc;
10162         }
10163
10164         return offset;
10165 }
10166
10167
10168 static void
10169 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
10170     packet_info *pinfo, proto_tree *tree)
10171 {
10172         int i;
10173         int offset;
10174         guint length;
10175
10176         /*
10177          * Show the setup words.
10178          */
10179         if (s_tvb != NULL) {
10180                 length = tvb_reported_length(s_tvb);
10181                 for (i = 0, offset = 0; length >= 2;
10182                     i++, offset += 2, length -= 2) {
10183                         /*
10184                          * XXX - add a setup word filterable field?
10185                          */
10186                         proto_tree_add_text(tree, s_tvb, offset, 2,
10187                             "Setup Word %d: 0x%04x", i,
10188                             tvb_get_letohs(s_tvb, offset));
10189                 }
10190         }
10191
10192         /*
10193          * Show the parameters, if any.
10194          */
10195         if (p_tvb != NULL) {
10196                 length = tvb_reported_length(p_tvb);
10197                 if (length != 0) {
10198                         proto_tree_add_text(tree, p_tvb, 0, length,
10199                             "Parameters: %s",
10200                             tvb_bytes_to_str(p_tvb, 0, length));
10201                 }
10202         }
10203
10204         /*
10205          * Show the data, if any.
10206          */
10207         if (d_tvb != NULL) {
10208                 length = tvb_reported_length(d_tvb);
10209                 if (length != 0) {
10210                         proto_tree_add_text(tree, d_tvb, 0, length,
10211                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
10212                 }
10213         }
10214 }
10215
10216 /* This routine handles the following 4 calls
10217    Transaction  0x25
10218    Transaction Secondary 0x26
10219    Transaction2 0x32
10220    Transaction2 Secondary 0x33
10221 */
10222 static int
10223 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
10224 {
10225         guint8 wc, sc=0;
10226         int so=offset;
10227         int sl=0;
10228         int spo=offset;
10229         int spc=0;
10230         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
10231         int subcmd = -1;
10232         guint32 to;
10233         int an_len;
10234         const char *an = NULL;
10235         smb_info_t *si;
10236         smb_transact2_info_t *t2i;
10237         smb_transact_info_t *tri;
10238         guint16 bc;
10239         int padcnt;
10240         gboolean dissected_trans;
10241
10242         si = (smb_info_t *)pinfo->private_data;
10243
10244         WORD_COUNT;
10245
10246         if(wc==8){
10247                 /*secondary client request*/
10248
10249                 /* total param count, only a 16bit integer here*/
10250                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10251                 offset += 2;
10252         
10253                 /* total data count , only 16bit integer here*/
10254                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10255                 offset += 2;
10256
10257                 /* param count */
10258                 pc = tvb_get_letohs(tvb, offset);
10259                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
10260                 offset += 2;
10261
10262                 /* param offset */
10263                 po = tvb_get_letohs(tvb, offset);
10264                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
10265                 offset += 2;
10266
10267                 /* param disp */
10268                 pd = tvb_get_letohs(tvb, offset);
10269                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
10270                 offset += 2;
10271         
10272                 /* data count */
10273                 dc = tvb_get_letohs(tvb, offset);
10274                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
10275                 offset += 2;
10276
10277                 /* data offset */
10278                 od = tvb_get_letohs(tvb, offset);
10279                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
10280                 offset += 2;
10281         
10282                 /* data disp */
10283                 dd = tvb_get_letohs(tvb, offset);
10284                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
10285                 offset += 2;
10286
10287                 if(si->cmd==SMB_COM_TRANSACTION2){
10288                         guint16 fid;
10289
10290                         /* fid */
10291                         fid = tvb_get_letohs(tvb, offset);
10292                         add_fid(tvb, pinfo, tree, offset, 2, fid);
10293
10294                         offset += 2;
10295                 }
10296
10297                 /* There are no setup words. */
10298                 so = offset;
10299                 sc = 0;
10300                 sl = 0;
10301         } else {
10302                 /* it is not a secondary request */
10303
10304                 /* total param count , only a 16 bit integer here*/
10305                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10306                 offset += 2;
10307
10308                 /* total data count , only 16bit integer here*/
10309                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10310                 offset += 2;
10311
10312                 /* max param count , only 16bit integer here*/
10313                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10314                 offset += 2;
10315
10316                 /* max data count, only 16bit integer here*/
10317                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10318                 offset += 2;
10319
10320                 /* max setup count, only 16bit integer here*/
10321                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
10322                 offset += 1;
10323
10324                 /* reserved byte */
10325                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
10326                 offset += 1;
10327
10328                 /* transaction flags */
10329                 tf = dissect_transaction_flags(tvb, pinfo, tree, offset);
10330                 offset += 2;
10331
10332                 /* timeout */
10333                 to = tvb_get_letohl(tvb, offset);
10334                 if (to == 0)
10335                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
10336                 else if (to == 0xffffffff)
10337                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
10338                 else
10339                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
10340                 offset += 4;
10341
10342                 /* 2 reserved bytes */
10343                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10344                 offset += 2;
10345
10346                 /* param count */
10347                 pc = tvb_get_letohs(tvb, offset);
10348                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
10349                 offset += 2;
10350         
10351                 /* param offset */
10352                 po = tvb_get_letohs(tvb, offset);
10353                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
10354                 offset += 2;
10355
10356                 /* param displacement is zero here */
10357                 pd = 0;
10358
10359                 /* data count */
10360                 dc = tvb_get_letohs(tvb, offset);
10361                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
10362                 offset += 2;
10363
10364                 /* data offset */
10365                 od = tvb_get_letohs(tvb, offset);
10366                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
10367                 offset += 2;
10368
10369                 /* data displacement is zero here */
10370                 dd = 0;
10371
10372                 /* setup count */
10373                 sc = tvb_get_guint8(tvb, offset);
10374                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
10375                 offset += 1;
10376
10377                 /* reserved byte */
10378                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
10379                 offset += 1;
10380                 
10381                 /* this is where the setup bytes, if any start */       
10382                 so = offset;
10383                 sl = sc*2;
10384
10385                 /* if there were any setup bytes, decode them */
10386                 if(sc){
10387                         switch(si->cmd){
10388
10389                         case SMB_COM_TRANSACTION2:
10390                                 /* TRANSACTION2 only has one setup word and
10391                                    that is the subcommand code. */
10392                                 subcmd = tvb_get_letohs(tvb, offset);
10393                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
10394                                     tvb, offset, 2, subcmd);
10395                                 if (check_col(pinfo->cinfo, COL_INFO)) {
10396                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10397                                             val_to_str(subcmd, trans2_cmd_vals, 
10398                                                 "Unknown (0x%02x)"));
10399                                 }
10400                                 if (!si->unidir) {
10401                                         if(!pinfo->fd->flags.visited){
10402                                                 /* 
10403                                                  * Allocate a new
10404                                                  * smb_transact2_info_t
10405                                                  * structure.
10406                                                  */
10407                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
10408                                                 t2i->subcmd = subcmd;
10409                                                 t2i->info_level = -1;
10410                                                 t2i->resume_keys = FALSE;
10411                                                 si->sip->extra_info = t2i;
10412                                         }
10413                                 }     
10414                                 break;
10415
10416                         case SMB_COM_TRANSACTION:
10417                                 /* TRANSACTION setup words processed below */
10418                                 break;
10419                         }
10420
10421                         offset += sl;
10422                 }
10423         }
10424
10425         BYTE_COUNT;
10426         
10427         if(wc!=8){
10428                 /* primary request */
10429                 /* name is NULL if transaction2 */
10430                 if(si->cmd == SMB_COM_TRANSACTION){
10431                         /* Transaction Name */
10432                         an = get_unicode_or_ascii_string(tvb, &offset,
10433                                 pinfo, &an_len, FALSE, FALSE, &bc);
10434                         if (an == NULL)
10435                                 goto endofcommand;
10436                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
10437                                 offset, an_len, an);
10438                         COUNT_BYTES(an_len);
10439                 }
10440         }
10441
10442         /*
10443          * The pipe or mailslot arguments for Transaction start with
10444          * the first setup word (or where the first setup word would
10445          * be if there were any setup words), and run to the current
10446          * offset (which could mean that there aren't any).
10447          */
10448         spo = so;
10449         spc = offset - spo;
10450
10451         /* parameters */
10452         if(po>offset){
10453                 /* We have some initial padding bytes.
10454                 */
10455                 padcnt = po-offset;
10456                 if (padcnt > bc)
10457                         padcnt = bc;
10458                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
10459                 COUNT_BYTES(padcnt);
10460         }
10461         if(pc){
10462                 CHECK_BYTE_COUNT(pc);
10463                 switch(si->cmd) {
10464
10465                 case SMB_COM_TRANSACTION2:
10466                         /* TRANSACTION2 parameters*/
10467                         offset = dissect_transaction2_request_parameters(tvb,
10468                             pinfo, tree, offset, subcmd, pc);
10469                         bc -= pc;
10470                         break;
10471
10472                 case SMB_COM_TRANSACTION:
10473                         /* TRANSACTION parameters processed below */
10474                         COUNT_BYTES(pc);
10475                         break;
10476                 }
10477         }
10478
10479         /* data */
10480         if(od>offset){
10481                 /* We have some initial padding bytes.
10482                 */
10483                 padcnt = od-offset;
10484                 if (padcnt > bc)
10485                         padcnt = bc;
10486                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
10487                 COUNT_BYTES(padcnt);
10488         }
10489         if(dc){
10490                 CHECK_BYTE_COUNT(dc);
10491                 switch(si->cmd){
10492
10493                 case SMB_COM_TRANSACTION2:
10494                         /* TRANSACTION2 data*/
10495                         offset = dissect_transaction2_request_data(tvb, pinfo,
10496                             tree, offset, subcmd, dc);
10497                         bc -= dc;
10498                         break;
10499
10500                 case SMB_COM_TRANSACTION:
10501                         /* TRANSACTION data processed below */
10502                         COUNT_BYTES(dc);
10503                         break;
10504                 }
10505         }
10506
10507         /*TRANSACTION request parameters */
10508         if(si->cmd==SMB_COM_TRANSACTION){
10509                 /*XXX replace this block with a function and use that one 
10510                      for both requests/responses*/
10511                 if(dd==0){
10512                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
10513                         tvbuff_t *sp_tvb, *pd_tvb;
10514
10515                         if(pc>0){
10516                                 if(pc>tvb_length_remaining(tvb, po)){
10517                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
10518                                 } else {
10519                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
10520                                 }
10521                         } else {
10522                                 p_tvb = NULL;
10523                         }
10524                         if(dc>0){
10525                                 if(dc>tvb_length_remaining(tvb, od)){
10526                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
10527                                 } else {
10528                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
10529                                 }
10530                         } else {
10531                                 d_tvb = NULL;
10532                         }
10533                         if(sl){
10534                                 if(sl>tvb_length_remaining(tvb, so)){
10535                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
10536                                 } else {
10537                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
10538                                 }
10539                         } else {
10540                                 s_tvb = NULL;
10541                         }
10542
10543                         if (!si->unidir) {
10544                                 if(!pinfo->fd->flags.visited){
10545                                         /* 
10546                                          * Allocate a new smb_transact_info_t
10547                                          * structure.
10548                                          */
10549                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
10550                                         tri->subcmd = -1;
10551                                         tri->trans_subcmd = -1;
10552                                         tri->function = -1;
10553                                         tri->fid = -1;
10554                                         tri->lanman_cmd = 0;
10555                                         tri->param_descrip = NULL;
10556                                         tri->data_descrip = NULL;
10557                                         tri->aux_data_descrip = NULL;
10558                                         tri->info_level = -1;
10559                                         si->sip->extra_info = tri;
10560                                 } else {
10561                                         /*
10562                                          * We already filled the structure
10563                                          * in; don't bother doing so again.
10564                                          */
10565                                         tri = NULL;
10566                                 }
10567                         } else {
10568                                 /*
10569                                  * This is a unidirectional message, for
10570                                  * which there will be no reply; don't
10571                                  * bother allocating an "smb_transact_info_t"
10572                                  * structure for it.
10573                                  */
10574                                 tri = NULL;
10575                         }
10576                         dissected_trans = FALSE;
10577                         if(strncmp("\\PIPE\\", an, 6) == 0){
10578                                 if (tri != NULL)
10579                                         tri->subcmd=TRANSACTION_PIPE;
10580
10581                                 /*
10582                                  * A tvbuff containing the setup words and
10583                                  * the pipe path.
10584                                  */
10585                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
10586
10587                                 /*
10588                                  * A tvbuff containing the parameters and the
10589                                  * data.
10590                                  */
10591                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
10592
10593                                 dissected_trans = dissect_pipe_smb(sp_tvb,
10594                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
10595                                     top_tree);
10596                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
10597                                 if (tri != NULL)
10598                                         tri->subcmd=TRANSACTION_MAILSLOT;
10599
10600                                 /*
10601                                  * A tvbuff containing the setup words and
10602                                  * the mailslot path.
10603                                  */
10604                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
10605                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
10606                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
10607                         }
10608                         if (!dissected_trans) {
10609                                 dissect_trans_data(s_tvb, p_tvb, d_tvb,
10610                                     pinfo, tree);
10611                         }
10612                 } else {
10613                         if(check_col(pinfo->cinfo, COL_INFO)){
10614                                 col_append_str(pinfo->cinfo, COL_INFO,
10615                                         "[transact continuation]");
10616                         }
10617                 }
10618         }
10619
10620         END_OF_SMB
10621
10622         return offset;
10623 }
10624
10625  
10626
10627 static int
10628 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10629     int offset, guint16 *bcp, gboolean *trunc)
10630 {
10631         int fn_len;
10632         const char *fn;
10633         int old_offset = offset;
10634         proto_item *item = NULL;
10635         proto_tree *tree = NULL;
10636         smb_info_t *si;
10637         smb_transact2_info_t *t2i;
10638         gboolean resume_keys = FALSE;
10639
10640         si = (smb_info_t *)pinfo->private_data;
10641         if (si->sip != NULL) {
10642                 t2i = si->sip->extra_info;
10643                 if (t2i != NULL)
10644                         resume_keys = t2i->resume_keys;
10645         }
10646
10647         if(parent_tree){
10648                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10649                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10650                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10651         }
10652
10653         if (resume_keys) {
10654                 /* resume key */
10655                 CHECK_BYTE_COUNT_SUBR(4);
10656                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
10657                 COUNT_BYTES_SUBR(4);
10658         }
10659
10660         /* create time */
10661         CHECK_BYTE_COUNT_SUBR(4);
10662         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10663                 hf_smb_create_time,
10664                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
10665         *bcp -= 4;
10666
10667         /* access time */
10668         CHECK_BYTE_COUNT_SUBR(4);
10669         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10670                 hf_smb_access_time,
10671                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
10672         *bcp -= 4;
10673
10674         /* last write time */
10675         CHECK_BYTE_COUNT_SUBR(4);
10676         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10677                 hf_smb_last_write_time,
10678                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
10679         *bcp -= 4;
10680
10681         /* data size */
10682         CHECK_BYTE_COUNT_SUBR(4);
10683         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10684         COUNT_BYTES_SUBR(4);
10685
10686         /* allocation size */
10687         CHECK_BYTE_COUNT_SUBR(4);
10688         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10689         COUNT_BYTES_SUBR(4);
10690
10691         /* File Attributes */
10692         CHECK_BYTE_COUNT_SUBR(2);
10693         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
10694         *bcp -= 2;
10695
10696         /* file name len */
10697         CHECK_BYTE_COUNT_SUBR(1);
10698         fn_len = tvb_get_guint8(tvb, offset);
10699         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
10700         COUNT_BYTES_SUBR(1);
10701         if (si->unicode)
10702                 fn_len += 2;    /* include terminating '\0' */
10703         else
10704                 fn_len++;       /* include terminating '\0' */
10705
10706         /* file name */
10707         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10708         CHECK_STRING_SUBR(fn);
10709         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10710                 fn);
10711         COUNT_BYTES_SUBR(fn_len);
10712
10713         if (check_col(pinfo->cinfo, COL_INFO)) {
10714                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10715                 fn);
10716         }
10717  
10718         proto_item_append_text(item, " File: %s", fn);
10719         proto_item_set_len(item, offset-old_offset);
10720
10721         *trunc = FALSE;
10722         return offset;
10723 }
10724
10725 static int
10726 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10727     int offset, guint16 *bcp, gboolean *trunc)
10728 {
10729         int fn_len;
10730         const char *fn;
10731         int old_offset = offset;
10732         proto_item *item = NULL;
10733         proto_tree *tree = NULL;
10734         smb_info_t *si;
10735         smb_transact2_info_t *t2i;
10736         gboolean resume_keys = FALSE;
10737
10738         si = (smb_info_t *)pinfo->private_data;
10739         if (si->sip != NULL) {
10740                 t2i = si->sip->extra_info;
10741                 if (t2i != NULL)
10742                         resume_keys = t2i->resume_keys;
10743         }
10744
10745         if(parent_tree){
10746                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10747                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10748                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10749         }
10750
10751         if (resume_keys) {
10752                 /* resume key */
10753                 CHECK_BYTE_COUNT_SUBR(4);
10754                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
10755                 COUNT_BYTES_SUBR(4);
10756         }
10757  
10758         /* create time */
10759         CHECK_BYTE_COUNT_SUBR(4);
10760         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10761                 hf_smb_create_time,
10762                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
10763         *bcp -= 4;
10764
10765         /* access time */
10766         CHECK_BYTE_COUNT_SUBR(4);
10767         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10768                 hf_smb_access_time,
10769                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
10770         *bcp -= 4;
10771
10772         /* last write time */
10773         CHECK_BYTE_COUNT_SUBR(4);
10774         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10775                 hf_smb_last_write_time,
10776                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
10777         *bcp -= 4;
10778
10779         /* data size */
10780         CHECK_BYTE_COUNT_SUBR(4);
10781         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10782         COUNT_BYTES_SUBR(4);
10783
10784         /* allocation size */
10785         CHECK_BYTE_COUNT_SUBR(4);
10786         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10787         COUNT_BYTES_SUBR(4);
10788
10789         /* File Attributes */
10790         CHECK_BYTE_COUNT_SUBR(2);
10791         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
10792         *bcp -= 2;
10793
10794         /* ea size */
10795         CHECK_BYTE_COUNT_SUBR(4);
10796         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10797         COUNT_BYTES_SUBR(4);
10798
10799         /* file name len */
10800         CHECK_BYTE_COUNT_SUBR(1);
10801         fn_len = tvb_get_guint8(tvb, offset);
10802         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
10803         COUNT_BYTES_SUBR(1);
10804
10805         /* file name */
10806         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10807         CHECK_STRING_SUBR(fn);
10808         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10809                 fn);
10810         COUNT_BYTES_SUBR(fn_len);
10811         if (si->unicode)
10812                 fn_len += 2;    /* include terminating '\0' */
10813         else
10814                 fn_len++;       /* include terminating '\0' */
10815
10816         if (check_col(pinfo->cinfo, COL_INFO)) {
10817                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10818                 fn);
10819         }
10820
10821         proto_item_append_text(item, " File: %s", fn);
10822         proto_item_set_len(item, offset-old_offset);
10823
10824         *trunc = FALSE;
10825         return offset;
10826 }
10827
10828 static int
10829 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10830     int offset, guint16 *bcp, gboolean *trunc)
10831 {
10832         int fn_len;
10833         const char *fn;
10834         int old_offset = offset;
10835         proto_item *item = NULL;
10836         proto_tree *tree = NULL;
10837         smb_info_t *si;
10838         guint32 neo;
10839         int padcnt;
10840
10841         si = (smb_info_t *)pinfo->private_data;
10842
10843         if(parent_tree){
10844                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10845                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10846                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10847         }
10848
10849         /*
10850          * We assume that the presence of a next entry offset implies the
10851          * absence of a resume key, as appears to be the case for 4.3.4.6.
10852          */
10853
10854         /* next entry offset */
10855         CHECK_BYTE_COUNT_SUBR(4);
10856         neo = tvb_get_letohl(tvb, offset);
10857         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10858         COUNT_BYTES_SUBR(4);
10859         
10860         /* file index */
10861         CHECK_BYTE_COUNT_SUBR(4);
10862         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
10863         COUNT_BYTES_SUBR(4);
10864
10865         /* create time */
10866         CHECK_BYTE_COUNT_SUBR(8);
10867         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10868                 hf_smb_create_time);
10869         *bcp -= 8;
10870         
10871         /* access time */
10872         CHECK_BYTE_COUNT_SUBR(8);
10873         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10874                 hf_smb_access_time);
10875         *bcp -= 8;
10876         
10877         /* last write time */
10878         CHECK_BYTE_COUNT_SUBR(8);
10879         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10880                 hf_smb_last_write_time);
10881         *bcp -= 8;
10882         
10883         /* last change time */
10884         CHECK_BYTE_COUNT_SUBR(8);
10885         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10886                 hf_smb_change_time);
10887         *bcp -= 8;
10888         
10889         /* end of file */
10890         CHECK_BYTE_COUNT_SUBR(8);
10891         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10892         COUNT_BYTES_SUBR(8);
10893
10894         /* allocation size */
10895         CHECK_BYTE_COUNT_SUBR(8);
10896         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10897         COUNT_BYTES_SUBR(8);
10898
10899         /* Extended File Attributes */
10900         CHECK_BYTE_COUNT_SUBR(4);
10901         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
10902         *bcp -= 4;
10903
10904         /* file name len */
10905         CHECK_BYTE_COUNT_SUBR(4);
10906         fn_len = tvb_get_letohl(tvb, offset);
10907         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
10908         COUNT_BYTES_SUBR(4);
10909
10910         /* file name */
10911         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10912         CHECK_STRING_SUBR(fn);
10913         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10914                 fn);
10915         COUNT_BYTES_SUBR(fn_len);
10916
10917         if (check_col(pinfo->cinfo, COL_INFO)) {
10918                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10919                 fn);
10920         }
10921
10922         /* skip to next structure */
10923         if(neo){
10924                 padcnt = (old_offset + neo) - offset;
10925                 if (padcnt < 0) {
10926                         /*
10927                          * XXX - this is bogus; flag it?
10928                          */
10929                         padcnt = 0;
10930                 }
10931                 if (padcnt != 0) {
10932                         CHECK_BYTE_COUNT_SUBR(padcnt);
10933                         COUNT_BYTES_SUBR(padcnt);
10934                 }
10935         }
10936
10937         proto_item_append_text(item, " File: %s", fn);
10938         proto_item_set_len(item, offset-old_offset);
10939
10940         *trunc = FALSE;
10941         return offset;
10942 }
10943
10944 static int
10945 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10946     int offset, guint16 *bcp, gboolean *trunc)
10947 {
10948         int fn_len;
10949         const char *fn;
10950         int old_offset = offset;
10951         proto_item *item = NULL;
10952         proto_tree *tree = NULL;
10953         smb_info_t *si;
10954         guint32 neo;
10955         int padcnt;
10956
10957         si = (smb_info_t *)pinfo->private_data;
10958
10959         if(parent_tree){
10960                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10961                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10962                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10963         }
10964
10965         /*
10966          * We assume that the presence of a next entry offset implies the
10967          * absence of a resume key, as appears to be the case for 4.3.4.6.
10968          */
10969
10970         /* next entry offset */
10971         CHECK_BYTE_COUNT_SUBR(4);
10972         neo = tvb_get_letohl(tvb, offset);
10973         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10974         COUNT_BYTES_SUBR(4);
10975         
10976         /* file index */
10977         CHECK_BYTE_COUNT_SUBR(4);
10978         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
10979         COUNT_BYTES_SUBR(4);
10980
10981         /* create time */
10982         CHECK_BYTE_COUNT_SUBR(8);
10983         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10984                 hf_smb_create_time);
10985         *bcp -= 8;
10986         
10987         /* access time */
10988         CHECK_BYTE_COUNT_SUBR(8);
10989         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10990                 hf_smb_access_time);
10991         *bcp -= 8;
10992         
10993         /* last write time */
10994         CHECK_BYTE_COUNT_SUBR(8);
10995         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10996                 hf_smb_last_write_time);
10997         *bcp -= 8;
10998         
10999         /* last change time */
11000         CHECK_BYTE_COUNT_SUBR(8);
11001         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
11002                 hf_smb_change_time);
11003         *bcp -= 8;
11004         
11005         /* end of file */
11006         CHECK_BYTE_COUNT_SUBR(8);
11007         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11008         COUNT_BYTES_SUBR(8);
11009
11010         /* allocation size */
11011         CHECK_BYTE_COUNT_SUBR(8);
11012         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11013         COUNT_BYTES_SUBR(8);
11014
11015         /* Extended File Attributes */
11016         CHECK_BYTE_COUNT_SUBR(4);
11017         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
11018         *bcp -= 4;
11019
11020         /* file name len */
11021         CHECK_BYTE_COUNT_SUBR(4);
11022         fn_len = tvb_get_letohl(tvb, offset);
11023         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11024         COUNT_BYTES_SUBR(4);
11025
11026         /* ea size */
11027         CHECK_BYTE_COUNT_SUBR(4);
11028         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
11029         COUNT_BYTES_SUBR(4);
11030
11031         /* file name */
11032         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11033         CHECK_STRING_SUBR(fn);
11034         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11035                 fn);
11036         COUNT_BYTES_SUBR(fn_len);
11037
11038         if (check_col(pinfo->cinfo, COL_INFO)) {
11039                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11040                 fn);
11041         }
11042
11043         /* skip to next structure */
11044         if(neo){
11045                 padcnt = (old_offset + neo) - offset;
11046                 if (padcnt < 0) {
11047                         /*
11048                          * XXX - this is bogus; flag it?
11049                          */
11050                         padcnt = 0;
11051                 }
11052                 if (padcnt != 0) {
11053                         CHECK_BYTE_COUNT_SUBR(padcnt);
11054                         COUNT_BYTES_SUBR(padcnt);
11055                 }
11056         }
11057
11058         proto_item_append_text(item, " File: %s", fn);
11059         proto_item_set_len(item, offset-old_offset);
11060
11061         *trunc = FALSE;
11062         return offset;
11063 }
11064
11065 static int
11066 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11067     int offset, guint16 *bcp, gboolean *trunc)
11068 {
11069         int fn_len, sfn_len;
11070         const char *fn, *sfn;
11071         int old_offset = offset;
11072         proto_item *item = NULL;
11073         proto_tree *tree = NULL;
11074         smb_info_t *si;
11075         guint32 neo;
11076         int padcnt;
11077
11078         si = (smb_info_t *)pinfo->private_data;
11079
11080         if(parent_tree){
11081                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11082                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11083                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11084         }
11085
11086         /*
11087          * XXX - I have not seen any of these that contain a resume
11088          * key, even though some of the requests had the "return resume
11089          * key" flag set.
11090          */
11091
11092         /* next entry offset */
11093         CHECK_BYTE_COUNT_SUBR(4);
11094         neo = tvb_get_letohl(tvb, offset);
11095         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11096         COUNT_BYTES_SUBR(4);
11097         
11098         /* file index */
11099         CHECK_BYTE_COUNT_SUBR(4);
11100         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11101         COUNT_BYTES_SUBR(4);
11102
11103         /* create time */
11104         CHECK_BYTE_COUNT_SUBR(8);
11105         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
11106                 hf_smb_create_time);
11107         *bcp -= 8;
11108         
11109         /* access time */
11110         CHECK_BYTE_COUNT_SUBR(8);
11111         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
11112                 hf_smb_access_time);
11113         *bcp -= 8;
11114         
11115         /* last write time */
11116         CHECK_BYTE_COUNT_SUBR(8);
11117         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
11118                 hf_smb_last_write_time);
11119         *bcp -= 8;
11120         
11121         /* last change time */
11122         CHECK_BYTE_COUNT_SUBR(8);
11123         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
11124                 hf_smb_change_time);
11125         *bcp -= 8;
11126         
11127         /* end of file */
11128         CHECK_BYTE_COUNT_SUBR(8);
11129         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11130         COUNT_BYTES_SUBR(8);
11131
11132         /* allocation size */
11133         CHECK_BYTE_COUNT_SUBR(8);
11134         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11135         COUNT_BYTES_SUBR(8);
11136
11137         /* Extended File Attributes */
11138         CHECK_BYTE_COUNT_SUBR(4);
11139         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
11140         *bcp -= 4;
11141
11142         /* file name len */
11143         CHECK_BYTE_COUNT_SUBR(4);
11144         fn_len = tvb_get_letohl(tvb, offset);
11145         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11146         COUNT_BYTES_SUBR(4);
11147
11148         /* ea size */
11149         CHECK_BYTE_COUNT_SUBR(4);
11150         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
11151         COUNT_BYTES_SUBR(4);
11152
11153         /* short file name len */
11154         CHECK_BYTE_COUNT_SUBR(1);
11155         sfn_len = tvb_get_guint8(tvb, offset);
11156         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
11157         COUNT_BYTES_SUBR(1);
11158
11159         /* reserved byte */
11160         CHECK_BYTE_COUNT_SUBR(1);
11161         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11162         COUNT_BYTES_SUBR(1);
11163  
11164         /* short file name */
11165         sfn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &sfn_len, FALSE, TRUE, bcp);
11166         CHECK_STRING_SUBR(sfn);
11167         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
11168                 sfn);
11169         COUNT_BYTES_SUBR(24);
11170
11171         /* file name */
11172         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11173         CHECK_STRING_SUBR(fn);
11174         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11175                 fn);
11176         COUNT_BYTES_SUBR(fn_len);
11177
11178         if (check_col(pinfo->cinfo, COL_INFO)) {
11179                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11180                 fn);
11181         }
11182
11183         /* skip to next structure */
11184         if(neo){
11185                 padcnt = (old_offset + neo) - offset;
11186                 if (padcnt < 0) {
11187                         /*
11188                          * XXX - this is bogus; flag it?
11189                          */
11190                         padcnt = 0;
11191                 }
11192                 if (padcnt != 0) {
11193                         CHECK_BYTE_COUNT_SUBR(padcnt);
11194                         COUNT_BYTES_SUBR(padcnt);
11195                 }
11196         }
11197
11198         proto_item_append_text(item, " File: %s", fn);
11199         proto_item_set_len(item, offset-old_offset);
11200
11201         *trunc = FALSE;
11202         return offset;
11203 }
11204
11205 static int
11206 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11207     int offset, guint16 *bcp, gboolean *trunc)
11208 {
11209         int fn_len;
11210         const char *fn;
11211         int old_offset = offset;
11212         proto_item *item = NULL;
11213         proto_tree *tree = NULL;
11214         smb_info_t *si;
11215         guint32 neo;
11216         int padcnt;
11217
11218         si = (smb_info_t *)pinfo->private_data;
11219
11220         if(parent_tree){
11221                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
11222                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
11223                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11224         }
11225
11226         /*
11227          * We assume that the presence of a next entry offset implies the
11228          * absence of a resume key, as appears to be the case for 4.3.4.6.
11229          */
11230
11231         /* next entry offset */
11232         CHECK_BYTE_COUNT_SUBR(4);
11233         neo = tvb_get_letohl(tvb, offset);
11234         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11235         COUNT_BYTES_SUBR(4);
11236         
11237         /* file index */
11238         CHECK_BYTE_COUNT_SUBR(4);
11239         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
11240         COUNT_BYTES_SUBR(4);
11241
11242         /* file name len */
11243         CHECK_BYTE_COUNT_SUBR(4);
11244         fn_len = tvb_get_letohl(tvb, offset);
11245         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
11246         COUNT_BYTES_SUBR(4);
11247
11248         /* file name */
11249         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11250         CHECK_STRING_SUBR(fn);
11251         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11252                 fn);
11253         COUNT_BYTES_SUBR(fn_len);
11254
11255         if (check_col(pinfo->cinfo, COL_INFO)) {
11256                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11257                 fn);
11258         }
11259
11260         /* skip to next structure */
11261         if(neo){
11262                 padcnt = (old_offset + neo) - offset;
11263                 if (padcnt < 0) {
11264                         /*
11265                          * XXX - this is bogus; flag it?
11266                          */
11267                         padcnt = 0;
11268                 }
11269                 if (padcnt != 0) {
11270                         CHECK_BYTE_COUNT_SUBR(padcnt);
11271                         COUNT_BYTES_SUBR(padcnt);
11272                 }
11273         }
11274
11275         proto_item_append_text(item, " File: %s", fn);
11276         proto_item_set_len(item, offset-old_offset);
11277
11278         *trunc = FALSE;
11279         return offset;
11280 }
11281  
11282 static int
11283 dissect_4_3_4_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11284     int offset, guint16 *bcp, gboolean *trunc)
11285 {
11286 /*XXX im lazy. i havnt implemented this */
11287         offset += *bcp;
11288         *bcp = 0;
11289         *trunc = FALSE;
11290         return offset;
11291 }
11292
11293 /*dissect the data block for TRANS2_FIND_FIRST2*/
11294 static int
11295 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
11296     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
11297 {
11298         smb_info_t *si;
11299
11300         if(!*bcp){
11301                 return offset;
11302         }
11303         
11304         si = (smb_info_t *)pinfo->private_data;
11305         switch(si->info_level){
11306         case 1:         /*Info Standard*/
11307                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
11308                     trunc);
11309                 break;
11310         case 2:         /*Info Query EA Size*/
11311                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
11312                     trunc);
11313                 break;
11314         case 3:         /*Info Query EAs From List same as 
11315                                 InfoQueryEASize*/
11316                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
11317                     trunc);
11318                 break;
11319         case 0x0101:    /*Find File Directory Info*/
11320                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
11321                     trunc);
11322                 break;
11323         case 0x0102:    /*Find File Full Directory Info*/
11324                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
11325                     trunc);
11326                 break;
11327         case 0x0103:    /*Find File Names Info*/
11328                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
11329                     trunc);
11330                 break;
11331         case 0x0104:    /*Find File Both Directory Info*/
11332                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
11333                     trunc);
11334                 break;
11335         case 0x0202:    /*Find File UNIX*/
11336                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
11337                     trunc);
11338                 break;
11339         default:        /* unknown info level */
11340                 *trunc = FALSE;
11341                 break;
11342         }
11343         return offset;
11344 }
11345
11346
11347 static int
11348 dissect_fs_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
11349 {
11350         guint32 mask;
11351         proto_item *item = NULL;
11352         proto_tree *tree = NULL;
11353
11354         mask = tvb_get_letohl(tvb, offset);
11355
11356         if(parent_tree){
11357                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
11358                         "FS Attributes: 0x%08x", mask);
11359                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
11360         }
11361
11362         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
11363                 tvb, offset, 4, mask);
11364         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
11365                 tvb, offset, 4, mask);
11366         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
11367                 tvb, offset, 4, mask);
11368         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
11369                 tvb, offset, 4, mask);
11370         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
11371                 tvb, offset, 4, mask);
11372         proto_tree_add_boolean(tree, hf_smb_fs_attr_dim,
11373                 tvb, offset, 4, mask);
11374         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
11375                 tvb, offset, 4, mask);
11376
11377         offset += 4;
11378         return offset;
11379 }
11380  
11381
11382 static int
11383 dissect_device_characteristics(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
11384 {
11385         guint32 mask;
11386         proto_item *item = NULL;
11387         proto_tree *tree = NULL;
11388
11389         mask = tvb_get_letohl(tvb, offset);
11390
11391         if(parent_tree){
11392                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
11393                         "Device Characteristics: 0x%08x", mask);
11394                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
11395         }
11396
11397         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
11398                 tvb, offset, 4, mask);
11399         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
11400                 tvb, offset, 4, mask);
11401         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
11402                 tvb, offset, 4, mask);
11403         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
11404                 tvb, offset, 4, mask);
11405         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
11406                 tvb, offset, 4, mask);
11407         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
11408                 tvb, offset, 4, mask);
11409         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
11410                 tvb, offset, 4, mask);
11411
11412         offset += 4;
11413         return offset;
11414 }
11415
11416 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
11417 static int
11418 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11419     int offset, guint16 *bcp)
11420 {
11421         smb_info_t *si;
11422         int fn_len, vll, fnl;
11423         const char *fn;
11424
11425         if(!*bcp){
11426                 return offset;
11427         }
11428         
11429         si = (smb_info_t *)pinfo->private_data;
11430         switch(si->info_level){
11431         case 1:         /* SMB_INFO_ALLOCATION */
11432                 /* filesystem id */
11433                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11434                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
11435                 COUNT_BYTES_TRANS_SUBR(4);
11436
11437                 /* sectors per unit */
11438                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11439                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
11440                 COUNT_BYTES_TRANS_SUBR(4);
11441
11442                 /* units */
11443                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11444                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
11445                 COUNT_BYTES_TRANS_SUBR(4);
11446
11447                 /* avail units */
11448                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11449                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
11450                 COUNT_BYTES_TRANS_SUBR(4);
11451
11452                 /* bytes per sector, only 16bit integer here */
11453                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11454                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11455                 COUNT_BYTES_TRANS_SUBR(2);
11456
11457                 break;
11458         case 2:         /* SMB_INFO_VOLUME */
11459                 /* volume serial number */
11460                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11461                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
11462                 COUNT_BYTES_TRANS_SUBR(4);
11463
11464                 /* volume label length, only one byte here */
11465                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
11466                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
11467                 COUNT_BYTES_TRANS_SUBR(1);
11468
11469                 /* label */
11470                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
11471                 CHECK_STRING_TRANS_SUBR(fn);
11472                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
11473                         fn);
11474                 COUNT_BYTES_TRANS_SUBR(fn_len);
11475
11476                 break;
11477         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
11478                 /* create time */
11479                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
11480                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
11481                         hf_smb_create_time);
11482                 *bcp -= 8;
11483         
11484                 /* volume serial number */
11485                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11486                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
11487                 COUNT_BYTES_TRANS_SUBR(4);
11488
11489                 /* volume label length */
11490                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11491                 vll = tvb_get_letohl(tvb, offset);
11492                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
11493                 COUNT_BYTES_TRANS_SUBR(4);
11494
11495                 /* 2 reserved bytes */
11496                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11497                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
11498                 COUNT_BYTES_TRANS_SUBR(2);
11499
11500                 /* label */
11501                 fn_len = vll;
11502                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11503                 CHECK_STRING_TRANS_SUBR(fn);
11504                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
11505                         fn);
11506                 COUNT_BYTES_TRANS_SUBR(fn_len);
11507
11508                 break;
11509         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
11510                 /* allocation size */
11511                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
11512                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11513                 COUNT_BYTES_TRANS_SUBR(8);
11514
11515                 /* free allocation units */
11516                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
11517                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
11518                 COUNT_BYTES_TRANS_SUBR(8);
11519
11520                 /* sectors per unit */
11521                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11522                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
11523                 COUNT_BYTES_TRANS_SUBR(4);
11524
11525                 /* bytes per sector */
11526                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11527                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
11528                 COUNT_BYTES_TRANS_SUBR(4);
11529
11530                 break;
11531         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
11532                 /* device type */
11533                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11534                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
11535                 COUNT_BYTES_TRANS_SUBR(4);
11536  
11537                 /* device characteristics */
11538                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11539                 offset = dissect_device_characteristics(tvb, pinfo, tree, offset);
11540                 *bcp -= 4;
11541         
11542                 break;
11543         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
11544                 /* FS attributes */
11545                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11546                 offset = dissect_fs_attributes(tvb, pinfo, tree, offset);
11547                 *bcp -= 4;
11548         
11549                 /* max name len */
11550                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11551                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
11552                 COUNT_BYTES_TRANS_SUBR(4);
11553
11554                 /* fs name length */
11555                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11556                 fnl = tvb_get_letohl(tvb, offset);
11557                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
11558                 COUNT_BYTES_TRANS_SUBR(4);
11559
11560                 /* label */
11561                 fn_len = fnl;
11562                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11563                 CHECK_STRING_TRANS_SUBR(fn);
11564                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
11565                         fn);
11566                 COUNT_BYTES_TRANS_SUBR(fn_len);
11567
11568                 break;
11569         case 1006:      /* QUERY_FS_QUOTA_INFO */
11570                 offset = dissect_nt_quota(tvb, pinfo, tree, offset, bcp);
11571         }
11572  
11573         return offset;
11574 }
11575  
11576 static int
11577 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
11578     proto_tree *parent_tree)
11579 {
11580         proto_item *item = NULL;
11581         proto_tree *tree = NULL;
11582         smb_info_t *si;
11583         smb_transact2_info_t *t2i;
11584         int count;
11585         gboolean trunc;
11586         int offset = 0;
11587         guint16 dc;
11588
11589         dc = tvb_reported_length(tvb);
11590
11591         si = (smb_info_t *)pinfo->private_data;
11592         if (si->sip != NULL)
11593                 t2i = si->sip->extra_info;
11594         else
11595                 t2i = NULL;
11596
11597         if(parent_tree){
11598                 if (t2i != NULL && t2i->subcmd != -1) {
11599                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
11600                                 "%s Data",
11601                                 val_to_str(t2i->subcmd, trans2_cmd_vals, 
11602                                         "Unknown (0x%02x)"));
11603                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
11604                 } else {
11605                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
11606                                 "Unknown Transaction2 Data");
11607                 }
11608         }
11609
11610         if (t2i == NULL) {
11611                 offset += dc;
11612                 return offset;
11613         }
11614         switch(t2i->subcmd){
11615         case 0x00:      /*TRANS2_OPEN2*/
11616                 /* XXX not implemented yet. See SNIA doc */
11617                 break;
11618         case 0x01:      /*TRANS2_FIND_FIRST2*/
11619                 /* returned data */
11620                 count = si->info_count;
11621
11622                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
11623                         col_append_fstr(pinfo->cinfo, COL_INFO,
11624                         ", Files:");
11625                 }
11626
11627                 while(count--){
11628                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
11629                                 offset, &dc, &trunc);
11630                         if (trunc)
11631                                 break;
11632                 }
11633                 break;
11634         case 0x02:      /*TRANS2_FIND_NEXT2*/
11635                 /* returned data */
11636                 count = si->info_count;
11637
11638                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
11639                         col_append_fstr(pinfo->cinfo, COL_INFO,
11640                         ", Files:");
11641                 }
11642
11643                 while(count--){
11644                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
11645                                 offset, &dc, &trunc);
11646                         if (trunc)
11647                                 break;
11648                 }
11649                 break;
11650         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
11651                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
11652                 break;
11653         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
11654                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
11655                 break;
11656         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
11657                 /* no data in this response */
11658                 break;
11659         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
11660                 /* identical to QUERY_PATH_INFO */
11661                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
11662                 break;
11663         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
11664                 /* no data in this response */
11665                 break;
11666         case 0x09:      /*TRANS2_FSCTL*/
11667                 /* XXX dont know how to dissect this one (yet)*/
11668                 break;
11669         case 0x0a:      /*TRANS2_IOCTL2*/
11670                 /* XXX dont know how to dissect this one (yet)*/
11671                 break;
11672         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11673                 /* XXX dont know how to dissect this one (yet)*/
11674                 break;
11675         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11676                 /* XXX dont know how to dissect this one (yet)*/
11677                 break;
11678         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11679                 /* no data in this response */
11680                 break;
11681         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11682                 /* XXX dont know how to dissect this one (yet)*/
11683                 break;
11684         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11685                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
11686                 break;
11687         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11688                 /* the SNIA spec appears to say the response has no data */
11689                 break;
11690         case -1:
11691                 /*
11692                  * We don't know what the matching request was; don't
11693                  * bother putting anything else into the tree for the data.
11694                  */
11695                 offset += dc;
11696                 dc = 0;
11697                 break;
11698         }
11699
11700         /* ooops there were data we didnt know how to process */
11701         if(dc != 0){
11702                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
11703                 offset += dc;
11704         }
11705
11706         return offset;
11707 }
11708
11709
11710 static void
11711 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
11712 {
11713         proto_item *item = NULL;
11714         proto_tree *tree = NULL;
11715         smb_info_t *si;
11716         smb_transact2_info_t *t2i;
11717         guint16 fid;
11718         int lno;
11719         int offset = 0;
11720         int pc;
11721
11722         pc = tvb_reported_length(tvb);
11723
11724         si = (smb_info_t *)pinfo->private_data;
11725         if (si->sip != NULL)
11726                 t2i = si->sip->extra_info;
11727         else
11728                 t2i = NULL;
11729
11730         if(parent_tree){
11731                 if (t2i != NULL && t2i->subcmd != -1) {
11732                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
11733                                 "%s Parameters",
11734                                 val_to_str(t2i->subcmd, trans2_cmd_vals, 
11735                                                 "Unknown (0x%02x)"));
11736                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
11737                 } else {
11738                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
11739                                 "Unknown Transaction2 Parameters");
11740                 }
11741         }
11742
11743         if (t2i == NULL) {
11744                 offset += pc;
11745                 return;
11746         }
11747         switch(t2i->subcmd){
11748         case 0x00:      /*TRANS2_OPEN2*/
11749                 /* fid */
11750                 fid = tvb_get_letohs(tvb, offset);
11751                 add_fid(tvb, pinfo, tree, offset, 2, fid);
11752                 offset += 2;
11753
11754                 /* File Attributes */
11755                 offset = dissect_file_attributes(tvb, pinfo, tree, offset);
11756
11757                 /* create time */
11758                 offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
11759                         hf_smb_create_time, 
11760                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
11761
11762                 /* data size */
11763                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11764                 offset += 4;
11765
11766                 /* granted access */
11767                 offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
11768
11769                 /* File Type */
11770                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
11771                 offset += 2;
11772
11773                 /* IPC State */
11774                 offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
11775
11776                 /* open_action */
11777                 offset = dissect_open_action(tvb, pinfo, tree, offset);
11778
11779                 /* 4 reserved bytes */
11780                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
11781                 offset += 4;
11782
11783                 /* ea error offset, only a 16 bit integer here */
11784                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11785                 offset += 2;
11786
11787                 /* ea length */
11788                 proto_tree_add_item(tree, hf_smb_ea_length, tvb, offset, 4, TRUE);
11789                 offset += 4;
11790
11791                 break;
11792         case 0x01:      /*TRANS2_FIND_FIRST2*/
11793                 /* Find First2 information level */
11794                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
11795
11796                 /* sid */
11797                 proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
11798                 offset += 2;
11799
11800                 /* search count */
11801                 si->info_count = tvb_get_letohs(tvb, offset);
11802                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
11803                 offset += 2;
11804
11805                 /* end of search */
11806                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
11807                 offset += 2;
11808
11809                 /* ea error offset, only a 16 bit integer here */
11810                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11811                 offset += 2;
11812
11813                 /* last name offset */
11814                 lno = tvb_get_letohs(tvb, offset);
11815                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
11816                 offset += 2;
11817
11818                 break;
11819         case 0x02:      /*TRANS2_FIND_NEXT2*/
11820                 /* search count */
11821                 si->info_count = tvb_get_letohs(tvb, offset);
11822                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
11823                 offset += 2;
11824
11825                 /* end of search */
11826                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
11827                 offset += 2;
11828
11829                 /* ea error offset , only a 16 bit integer here*/
11830                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11831                 offset += 2;
11832
11833                 /* last name offset */
11834                 lno = tvb_get_letohs(tvb, offset);
11835                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
11836                 offset += 2;
11837
11838                 break;
11839         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
11840                 /* no parameter block here */
11841                 break;
11842         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
11843                 /* no parameter block here */
11844                 break;
11845         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
11846                 /* no parameter block here */
11847                 break;
11848         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
11849                 /* no parameter block here */
11850                 break;
11851         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
11852                 /* no parameter block here */
11853                 break;
11854         case 0x09:      /*TRANS2_FSCTL*/
11855                 /* XXX dont know how to dissect this one (yet)*/
11856                 break;
11857         case 0x0a:      /*TRANS2_IOCTL2*/
11858                 /* XXX dont know how to dissect this one (yet)*/
11859                 break;
11860         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11861                 /* XXX dont know how to dissect this one (yet)*/
11862                 break;
11863         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11864                 /* XXX dont know how to dissect this one (yet)*/
11865                 break;
11866         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11867                 /* ea error offset, only a 16 bit integer here */
11868                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11869                 offset += 2;
11870
11871                 break;
11872         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11873                 /* XXX dont know how to dissect this one (yet)*/
11874                 break;
11875         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11876                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
11877                 break;
11878         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11879                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
11880                 break;
11881         case -1:
11882                 /*
11883                  * We don't know what the matching request was; don't
11884                  * bother putting anything else into the tree for the data.
11885                  */
11886                 offset += pc;
11887                 break;
11888         }
11889
11890         /* ooops there were data we didnt know how to process */
11891         if(offset<pc){
11892                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
11893                 offset += pc-offset;
11894         }
11895 }
11896
11897
11898 static int
11899 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
11900 {
11901         guint8 sc, wc;
11902         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
11903         gboolean reassembled = FALSE;
11904         smb_info_t *si;
11905         smb_transact2_info_t *t2i = NULL;
11906         guint16 bc;
11907         int padcnt;
11908         gboolean dissected_trans;
11909         fragment_data *r_fd = NULL;
11910         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
11911         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
11912         gboolean save_fragmented;
11913
11914         si = (smb_info_t *)pinfo->private_data;
11915
11916         switch(si->cmd){
11917         case SMB_COM_TRANSACTION2:
11918                 /* transaction2 */
11919                 if (si->sip != NULL) {
11920                         t2i = si->sip->extra_info;
11921                 } else
11922                         t2i = NULL;
11923                 if (t2i == NULL) {
11924                         /*
11925                          * We didn't see the matching request, so we don't
11926                          * know what type of transaction this is.
11927                          */
11928                         proto_tree_add_text(tree, tvb, 0, 0,
11929                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
11930                         if (check_col(pinfo->cinfo, COL_INFO)) {
11931                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
11932                         }
11933                 } else {
11934                         si->info_level = t2i->info_level;
11935                         if (t2i->subcmd == -1) {
11936                                 /*
11937                                  * We didn't manage to extract the subcommand
11938                                  * from the matching request (perhaps because
11939                                  * the frame was short), so we don't know what
11940                                  * type of transaction this is.
11941                                  */
11942                                 proto_tree_add_text(tree, tvb, 0, 0,
11943                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
11944                                 if (check_col(pinfo->cinfo, COL_INFO)) {
11945                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
11946                                 }
11947                         } else {
11948                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
11949                                 if (check_col(pinfo->cinfo, COL_INFO)) {
11950                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11951                                                 val_to_str(t2i->subcmd,
11952                                                         trans2_cmd_vals, 
11953                                                         "<unknown (0x%02x)>"));
11954                                 }
11955                         }
11956                 }
11957                 break;
11958         }
11959
11960         WORD_COUNT;
11961
11962         /* total param count, only a 16bit integer here */
11963         tp = tvb_get_letohs(tvb, offset);
11964         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
11965         offset += 2;
11966
11967         /* total data count, only a 16 bit integer here */
11968         td = tvb_get_letohs(tvb, offset);
11969         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
11970         offset += 2;
11971
11972         /* 2 reserved bytes */
11973         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
11974         offset += 2;
11975
11976         /* param count */
11977         pc = tvb_get_letohs(tvb, offset);
11978         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11979         offset += 2;
11980
11981         /* param offset */
11982         po = tvb_get_letohs(tvb, offset);
11983         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11984         offset += 2;
11985
11986         /* param disp */
11987         pd = tvb_get_letohs(tvb, offset);
11988         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
11989         offset += 2;
11990
11991         /* data count */
11992         dc = tvb_get_letohs(tvb, offset);
11993         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11994         offset += 2;
11995
11996         /* data offset */
11997         od = tvb_get_letohs(tvb, offset);
11998         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11999         offset += 2;
12000
12001         /* data disp */
12002         dd = tvb_get_letohs(tvb, offset);
12003         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
12004         offset += 2;
12005
12006         /* setup count */
12007         sc = tvb_get_guint8(tvb, offset);
12008         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
12009         offset += 1;
12010
12011         /* reserved byte */
12012         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12013         offset += 1;
12014
12015
12016         /* if there were any setup bytes, put them in a tvb for later */
12017         if(sc){
12018                 if((2*sc)>tvb_length_remaining(tvb, offset)){
12019                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
12020                 } else {
12021                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
12022                 }
12023                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
12024         } else {
12025                 s_tvb = NULL;
12026                 sp_tvb=NULL;
12027         }
12028         offset += 2*sc;
12029
12030
12031         BYTE_COUNT;
12032
12033
12034         /* reassembly of SMB Transaction data payload.
12035            In this section we do reassembly of both the data and parameters
12036            blocks of the SMB transaction command.
12037         */
12038         save_fragmented = pinfo->fragmented;
12039         /* do we need reassembly? */
12040         if( (td!=dc) || (tp!=pc) ){
12041                 /* oh yeah, either data or parameter section needs 
12042                    reassembly
12043                 */
12044                 pinfo->fragmented = TRUE;
12045                 if(smb_trans_reassembly){
12046                         /* ...and we were told to do reassembly */
12047                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
12048                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
12049                                                              po, pc, pd, td+tp);
12050                                 
12051                         }
12052                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
12053                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
12054                                                              od, dc, dd+tp, td+tp);
12055                         }
12056                 }
12057         }
12058
12059         /* if we got a reassembled fd structure from the reassembly routine we must
12060            create pd_tvb from it 
12061         */
12062         if(r_fd){
12063                 proto_tree *tr;
12064                 proto_item *it;
12065                 fragment_data *fd;
12066
12067                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
12068                                              r_fd->datalen);
12069                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
12070                 add_new_data_source(pinfo->fd, pd_tvb, "Reassembled SMB");
12071                 pinfo->fragmented = FALSE;
12072
12073                 it = proto_tree_add_text(tree, pd_tvb, 0, -1, "Fragments");
12074                 tr = proto_item_add_subtree(it, ett_smb_segments);
12075                 for(fd=r_fd->next;fd;fd=fd->next){
12076                         proto_tree_add_text(tr, pd_tvb, fd->offset, fd->len,
12077                                             "Frame:%u Data:%u-%u",
12078                                             fd->frame, fd->offset,
12079                                             fd->offset+fd->len-1);
12080                 }
12081         }
12082
12083
12084         if(pd_tvb){
12085                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
12086                 if(tp){
12087                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
12088                 }
12089                 if(td){
12090                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
12091                 }
12092         } else {
12093                 /* It was not reassembled. Do as best as we can.
12094                  * in this case we always try to dissect the stuff if 
12095                  * data and param displacement is 0. i.e. for the first
12096                  * (and maybe only) packet.
12097                  */
12098                 if( (pd==0) && (dd==0) ){
12099                         int min;
12100                         int reported_min;
12101                         min = MIN(pc,tvb_length_remaining(tvb,po));
12102                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
12103                         if(min && reported_min) {
12104                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
12105                         }
12106                         min = MIN(dc,tvb_length_remaining(tvb,od));
12107                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
12108                         if(min && reported_min) {
12109                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
12110                         }
12111                         /*
12112                          * A tvbuff containing the parameters
12113                          * and the data.
12114                          * XXX - check pc and dc as well?
12115                          */
12116                         if (tvb_length_remaining(tvb, po)){
12117                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
12118                         }
12119                 }
12120         }
12121
12122
12123
12124         /* parameters */
12125         if(po>offset){
12126                 /* We have some padding bytes.
12127                 */
12128                 padcnt = po-offset;
12129                 if (padcnt > bc)
12130                         padcnt = bc;
12131                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12132                 COUNT_BYTES(padcnt);
12133         }
12134         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
12135                 /* TRANSACTION2 parameters*/
12136                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
12137         }
12138         COUNT_BYTES(pc);
12139
12140
12141         /* data */
12142         if(od>offset){
12143                 /* We have some initial padding bytes.
12144                 */
12145                 padcnt = od-offset;
12146                 if (padcnt > bc)
12147                         padcnt = bc;
12148                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12149                 COUNT_BYTES(padcnt);
12150         }
12151         /*
12152          * If the data count is bigger than the count of bytes
12153          * remaining, clamp it so that the count of bytes remaining
12154          * doesn't go negative.
12155          */
12156         if (dc > bc)
12157                 dc = bc;
12158         COUNT_BYTES(dc);
12159
12160
12161
12162         /* from now on, everything is in separate tvbuffs so we dont count
12163            the bytes with COUNT_BYTES any more.
12164            neither do we reference offset any more (which by now points to the
12165            first byte AFTER this PDU */
12166
12167
12168         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
12169                 /* TRANSACTION2 parameters*/
12170                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
12171         }
12172
12173
12174         if(si->cmd==SMB_COM_TRANSACTION){
12175                 smb_transact_info_t *tri;
12176
12177                 dissected_trans = FALSE;
12178                 if (si->sip != NULL)
12179                         tri = si->sip->extra_info;
12180                 else
12181                         tri = NULL;
12182                 if (tri != NULL) {
12183                         switch(tri->subcmd){
12184
12185                         case TRANSACTION_PIPE:
12186                                 /* This function is safe to call for 
12187                                    s_tvb==sp_tvb==NULL, i.e. if we don't
12188                                    know them at this point.
12189                                    It's also safe to call if "p_tvb"
12190                                    or "d_tvb" are null.
12191                                 */
12192                                 if( pd_tvb) {
12193                                         dissected_trans = dissect_pipe_smb(
12194                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
12195                                                 d_tvb, NULL, pinfo, top_tree);
12196                                 }
12197                                 break;
12198                                 
12199                         case TRANSACTION_MAILSLOT:
12200                                 /* This one should be safe to call
12201                                    even if s_tvb and sp_tvb is NULL
12202                                 */
12203                                 if(d_tvb){
12204                                         dissected_trans = dissect_mailslot_smb(
12205                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
12206                                                 top_tree);
12207                                 }
12208                                 break;
12209                         }
12210                 }
12211                 if (!dissected_trans) {
12212                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
12213                         dissect_trans_data(s_tvb, p_tvb, d_tvb,
12214                                            pinfo, tree);
12215                 }
12216         }
12217
12218
12219         if( (p_tvb==0) && (d_tvb==0) ){
12220                 if(check_col(pinfo->cinfo, COL_INFO)){
12221                         col_append_str(pinfo->cinfo, COL_INFO,
12222                                        "[transact continuation]");
12223                 }
12224         }
12225
12226         pinfo->fragmented = save_fragmented;
12227         END_OF_SMB
12228
12229         return offset;
12230 }
12231
12232
12233 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
12234    END Transaction/Transaction2 Primary and secondary requests
12235    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
12236
12237
12238 static int
12239 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
12240 {
12241         guint8 wc;
12242         guint16 bc;
12243
12244         WORD_COUNT;
12245  
12246         if (wc != 0)
12247                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
12248
12249         BYTE_COUNT;
12250
12251         if (bc != 0)
12252                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
12253
12254         END_OF_SMB
12255
12256         return offset;
12257 }
12258
12259 typedef struct _smb_function {
12260        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
12261        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
12262 } smb_function;
12263
12264 static smb_function smb_dissector[256] = {
12265   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
12266   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
12267   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
12268   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
12269   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
12270   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
12271   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
12272   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
12273   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
12274   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
12275   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
12276   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
12277   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
12278   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
12279   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
12280   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
12281
12282   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
12283   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
12284   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
12285   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
12286   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
12287   /* 0x15 */  {dissect_unknown, dissect_unknown},
12288   /* 0x16 */  {dissect_unknown, dissect_unknown},
12289   /* 0x17 */  {dissect_unknown, dissect_unknown},
12290   /* 0x18 */  {dissect_unknown, dissect_unknown},
12291   /* 0x19 */  {dissect_unknown, dissect_unknown},
12292   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
12293   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
12294   /* 0x1c */  {dissect_unknown, dissect_unknown},
12295   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
12296   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
12297   /* 0x1f */  {dissect_unknown, dissect_unknown},
12298
12299   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
12300   /* 0x21 */  {dissect_unknown, dissect_unknown},
12301   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
12302   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
12303   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
12304   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
12305   /* 0x26 Transaction Secondary */  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
12306   /* 0x27 */  {dissect_unknown, dissect_unknown},
12307   /* 0x28 */  {dissect_unknown, dissect_unknown},
12308   /* 0x29 */  {dissect_unknown, dissect_unknown},
12309   /* 0x2a Move File*/  {dissect_move_request, dissect_move_response},
12310   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
12311   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
12312   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
12313   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
12314   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
12315
12316   /* 0x30 */  {dissect_unknown, dissect_unknown},
12317   /* 0x31 */  {dissect_unknown, dissect_unknown},
12318   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
12319   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
12320   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
12321   /* 0x35 */  {dissect_unknown, dissect_unknown},
12322   /* 0x36 */  {dissect_unknown, dissect_unknown},
12323   /* 0x37 */  {dissect_unknown, dissect_unknown},
12324   /* 0x38 */  {dissect_unknown, dissect_unknown},
12325   /* 0x39 */  {dissect_unknown, dissect_unknown},
12326   /* 0x3a */  {dissect_unknown, dissect_unknown},
12327   /* 0x3b */  {dissect_unknown, dissect_unknown},
12328   /* 0x3c */  {dissect_unknown, dissect_unknown},
12329   /* 0x3d */  {dissect_unknown, dissect_unknown},
12330   /* 0x3e */  {dissect_unknown, dissect_unknown},
12331   /* 0x3f */  {dissect_unknown, dissect_unknown},
12332
12333   /* 0x40 */  {dissect_unknown, dissect_unknown},
12334   /* 0x41 */  {dissect_unknown, dissect_unknown},
12335   /* 0x42 */  {dissect_unknown, dissect_unknown},
12336   /* 0x43 */  {dissect_unknown, dissect_unknown},
12337   /* 0x44 */  {dissect_unknown, dissect_unknown},
12338   /* 0x45 */  {dissect_unknown, dissect_unknown},
12339   /* 0x46 */  {dissect_unknown, dissect_unknown},
12340   /* 0x47 */  {dissect_unknown, dissect_unknown},
12341   /* 0x48 */  {dissect_unknown, dissect_unknown},
12342   /* 0x49 */  {dissect_unknown, dissect_unknown},
12343   /* 0x4a */  {dissect_unknown, dissect_unknown},
12344   /* 0x4b */  {dissect_unknown, dissect_unknown},
12345   /* 0x4c */  {dissect_unknown, dissect_unknown},
12346   /* 0x4d */  {dissect_unknown, dissect_unknown},
12347   /* 0x4e */  {dissect_unknown, dissect_unknown},
12348   /* 0x4f */  {dissect_unknown, dissect_unknown},
12349
12350   /* 0x50 */  {dissect_unknown, dissect_unknown},
12351   /* 0x51 */  {dissect_unknown, dissect_unknown},
12352   /* 0x52 */  {dissect_unknown, dissect_unknown},
12353   /* 0x53 */  {dissect_unknown, dissect_unknown},
12354   /* 0x54 */  {dissect_unknown, dissect_unknown},
12355   /* 0x55 */  {dissect_unknown, dissect_unknown},
12356   /* 0x56 */  {dissect_unknown, dissect_unknown},
12357   /* 0x57 */  {dissect_unknown, dissect_unknown},
12358   /* 0x58 */  {dissect_unknown, dissect_unknown},
12359   /* 0x59 */  {dissect_unknown, dissect_unknown},
12360   /* 0x5a */  {dissect_unknown, dissect_unknown},
12361   /* 0x5b */  {dissect_unknown, dissect_unknown},
12362   /* 0x5c */  {dissect_unknown, dissect_unknown},
12363   /* 0x5d */  {dissect_unknown, dissect_unknown},
12364   /* 0x5e */  {dissect_unknown, dissect_unknown},
12365   /* 0x5f */  {dissect_unknown, dissect_unknown},
12366
12367   /* 0x60 */  {dissect_unknown, dissect_unknown},
12368   /* 0x61 */  {dissect_unknown, dissect_unknown},
12369   /* 0x62 */  {dissect_unknown, dissect_unknown},
12370   /* 0x63 */  {dissect_unknown, dissect_unknown},
12371   /* 0x64 */  {dissect_unknown, dissect_unknown},
12372   /* 0x65 */  {dissect_unknown, dissect_unknown},
12373   /* 0x66 */  {dissect_unknown, dissect_unknown},
12374   /* 0x67 */  {dissect_unknown, dissect_unknown},
12375   /* 0x68 */  {dissect_unknown, dissect_unknown},
12376   /* 0x69 */  {dissect_unknown, dissect_unknown},
12377   /* 0x6a */  {dissect_unknown, dissect_unknown},
12378   /* 0x6b */  {dissect_unknown, dissect_unknown},
12379   /* 0x6c */  {dissect_unknown, dissect_unknown},
12380   /* 0x6d */  {dissect_unknown, dissect_unknown},
12381   /* 0x6e */  {dissect_unknown, dissect_unknown},
12382   /* 0x6f */  {dissect_unknown, dissect_unknown},
12383
12384   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
12385   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
12386   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
12387   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
12388   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
12389   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
12390   /* 0x76 */  {dissect_unknown, dissect_unknown},
12391   /* 0x77 */  {dissect_unknown, dissect_unknown},
12392   /* 0x78 */  {dissect_unknown, dissect_unknown},
12393   /* 0x79 */  {dissect_unknown, dissect_unknown},
12394   /* 0x7a */  {dissect_unknown, dissect_unknown},
12395   /* 0x7b */  {dissect_unknown, dissect_unknown},
12396   /* 0x7c */  {dissect_unknown, dissect_unknown},
12397   /* 0x7d */  {dissect_unknown, dissect_unknown},
12398   /* 0x7e */  {dissect_unknown, dissect_unknown},
12399   /* 0x7f */  {dissect_unknown, dissect_unknown},
12400
12401   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
12402   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
12403   /* 0x82 */  {dissect_unknown, dissect_unknown},
12404   /* 0x83 */  {dissect_unknown, dissect_unknown},
12405   /* 0x84 */  {dissect_unknown, dissect_unknown},
12406   /* 0x85 */  {dissect_unknown, dissect_unknown},
12407   /* 0x86 */  {dissect_unknown, dissect_unknown},
12408   /* 0x87 */  {dissect_unknown, dissect_unknown},
12409   /* 0x88 */  {dissect_unknown, dissect_unknown},
12410   /* 0x89 */  {dissect_unknown, dissect_unknown},
12411   /* 0x8a */  {dissect_unknown, dissect_unknown},
12412   /* 0x8b */  {dissect_unknown, dissect_unknown},
12413   /* 0x8c */  {dissect_unknown, dissect_unknown},
12414   /* 0x8d */  {dissect_unknown, dissect_unknown},
12415   /* 0x8e */  {dissect_unknown, dissect_unknown},
12416   /* 0x8f */  {dissect_unknown, dissect_unknown},
12417
12418   /* 0x90 */  {dissect_unknown, dissect_unknown},
12419   /* 0x91 */  {dissect_unknown, dissect_unknown},
12420   /* 0x92 */  {dissect_unknown, dissect_unknown},
12421   /* 0x93 */  {dissect_unknown, dissect_unknown},
12422   /* 0x94 */  {dissect_unknown, dissect_unknown},
12423   /* 0x95 */  {dissect_unknown, dissect_unknown},
12424   /* 0x96 */  {dissect_unknown, dissect_unknown},
12425   /* 0x97 */  {dissect_unknown, dissect_unknown},
12426   /* 0x98 */  {dissect_unknown, dissect_unknown},
12427   /* 0x99 */  {dissect_unknown, dissect_unknown},
12428   /* 0x9a */  {dissect_unknown, dissect_unknown},
12429   /* 0x9b */  {dissect_unknown, dissect_unknown},
12430   /* 0x9c */  {dissect_unknown, dissect_unknown},
12431   /* 0x9d */  {dissect_unknown, dissect_unknown},
12432   /* 0x9e */  {dissect_unknown, dissect_unknown},
12433   /* 0x9f */  {dissect_unknown, dissect_unknown},
12434   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
12435   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
12436   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
12437   /* 0xa3 */  {dissect_unknown, dissect_unknown},
12438   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
12439   /* 0xa5 */  {dissect_nt_rename_file_request, dissect_empty},
12440   /* 0xa6 */  {dissect_unknown, dissect_unknown},
12441   /* 0xa7 */  {dissect_unknown, dissect_unknown},
12442   /* 0xa8 */  {dissect_unknown, dissect_unknown},
12443   /* 0xa9 */  {dissect_unknown, dissect_unknown},
12444   /* 0xaa */  {dissect_unknown, dissect_unknown},
12445   /* 0xab */  {dissect_unknown, dissect_unknown},
12446   /* 0xac */  {dissect_unknown, dissect_unknown},
12447   /* 0xad */  {dissect_unknown, dissect_unknown},
12448   /* 0xae */  {dissect_unknown, dissect_unknown},
12449   /* 0xaf */  {dissect_unknown, dissect_unknown},
12450
12451   /* 0xb0 */  {dissect_unknown, dissect_unknown},
12452   /* 0xb1 */  {dissect_unknown, dissect_unknown},
12453   /* 0xb2 */  {dissect_unknown, dissect_unknown},
12454   /* 0xb3 */  {dissect_unknown, dissect_unknown},
12455   /* 0xb4 */  {dissect_unknown, dissect_unknown},
12456   /* 0xb5 */  {dissect_unknown, dissect_unknown},
12457   /* 0xb6 */  {dissect_unknown, dissect_unknown},
12458   /* 0xb7 */  {dissect_unknown, dissect_unknown},
12459   /* 0xb8 */  {dissect_unknown, dissect_unknown},
12460   /* 0xb9 */  {dissect_unknown, dissect_unknown},
12461   /* 0xba */  {dissect_unknown, dissect_unknown},
12462   /* 0xbb */  {dissect_unknown, dissect_unknown},
12463   /* 0xbc */  {dissect_unknown, dissect_unknown},
12464   /* 0xbd */  {dissect_unknown, dissect_unknown},
12465   /* 0xbe */  {dissect_unknown, dissect_unknown},
12466   /* 0xbf */  {dissect_unknown, dissect_unknown},
12467   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
12468   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
12469   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
12470   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
12471   /* 0xc4 */  {dissect_unknown, dissect_unknown},
12472   /* 0xc5 */  {dissect_unknown, dissect_unknown},
12473   /* 0xc6 */  {dissect_unknown, dissect_unknown},
12474   /* 0xc7 */  {dissect_unknown, dissect_unknown},
12475   /* 0xc8 */  {dissect_unknown, dissect_unknown},
12476   /* 0xc9 */  {dissect_unknown, dissect_unknown},
12477   /* 0xca */  {dissect_unknown, dissect_unknown},
12478   /* 0xcb */  {dissect_unknown, dissect_unknown},
12479   /* 0xcc */  {dissect_unknown, dissect_unknown},
12480   /* 0xcd */  {dissect_unknown, dissect_unknown},
12481   /* 0xce */  {dissect_unknown, dissect_unknown},
12482   /* 0xcf */  {dissect_unknown, dissect_unknown},
12483
12484   /* 0xd0 */  {dissect_unknown, dissect_unknown},
12485   /* 0xd1 */  {dissect_unknown, dissect_unknown},
12486   /* 0xd2 */  {dissect_unknown, dissect_unknown},
12487   /* 0xd3 */  {dissect_unknown, dissect_unknown},
12488   /* 0xd4 */  {dissect_unknown, dissect_unknown},
12489   /* 0xd5 */  {dissect_unknown, dissect_unknown},
12490   /* 0xd6 */  {dissect_unknown, dissect_unknown},
12491   /* 0xd7 */  {dissect_unknown, dissect_unknown},
12492   /* 0xd8 */  {dissect_unknown, dissect_unknown},
12493   /* 0xd9 */  {dissect_unknown, dissect_unknown},
12494   /* 0xda */  {dissect_unknown, dissect_unknown},
12495   /* 0xdb */  {dissect_unknown, dissect_unknown},
12496   /* 0xdc */  {dissect_unknown, dissect_unknown},
12497   /* 0xdd */  {dissect_unknown, dissect_unknown},
12498   /* 0xde */  {dissect_unknown, dissect_unknown},
12499   /* 0xdf */  {dissect_unknown, dissect_unknown},
12500
12501   /* 0xe0 */  {dissect_unknown, dissect_unknown},
12502   /* 0xe1 */  {dissect_unknown, dissect_unknown},
12503   /* 0xe2 */  {dissect_unknown, dissect_unknown},
12504   /* 0xe3 */  {dissect_unknown, dissect_unknown},
12505   /* 0xe4 */  {dissect_unknown, dissect_unknown},
12506   /* 0xe5 */  {dissect_unknown, dissect_unknown},
12507   /* 0xe6 */  {dissect_unknown, dissect_unknown},
12508   /* 0xe7 */  {dissect_unknown, dissect_unknown},
12509   /* 0xe8 */  {dissect_unknown, dissect_unknown},
12510   /* 0xe9 */  {dissect_unknown, dissect_unknown},
12511   /* 0xea */  {dissect_unknown, dissect_unknown},
12512   /* 0xeb */  {dissect_unknown, dissect_unknown},
12513   /* 0xec */  {dissect_unknown, dissect_unknown},
12514   /* 0xed */  {dissect_unknown, dissect_unknown},
12515   /* 0xee */  {dissect_unknown, dissect_unknown},
12516   /* 0xef */  {dissect_unknown, dissect_unknown},
12517
12518   /* 0xf0 */  {dissect_unknown, dissect_unknown},
12519   /* 0xf1 */  {dissect_unknown, dissect_unknown},
12520   /* 0xf2 */  {dissect_unknown, dissect_unknown},
12521   /* 0xf3 */  {dissect_unknown, dissect_unknown},
12522   /* 0xf4 */  {dissect_unknown, dissect_unknown},
12523   /* 0xf5 */  {dissect_unknown, dissect_unknown},
12524   /* 0xf6 */  {dissect_unknown, dissect_unknown},
12525   /* 0xf7 */  {dissect_unknown, dissect_unknown},
12526   /* 0xf8 */  {dissect_unknown, dissect_unknown},
12527   /* 0xf9 */  {dissect_unknown, dissect_unknown},
12528   /* 0xfa */  {dissect_unknown, dissect_unknown},
12529   /* 0xfb */  {dissect_unknown, dissect_unknown},
12530   /* 0xfc */  {dissect_unknown, dissect_unknown},
12531   /* 0xfd */  {dissect_unknown, dissect_unknown},
12532   /* 0xfe */  {dissect_unknown, dissect_unknown},
12533   /* 0xff */  {dissect_unknown, dissect_unknown},
12534 };
12535
12536 static int
12537 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree, int offset, proto_tree *smb_tree, guint8 cmd)
12538 {
12539         int old_offset = offset;
12540         smb_info_t *si;
12541  
12542         si = pinfo->private_data;
12543         if(cmd!=0xff){
12544                 proto_item *cmd_item;
12545                 proto_tree *cmd_tree;
12546                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
12547
12548                 if (check_col(pinfo->cinfo, COL_INFO)) {
12549                         col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
12550                                 decode_smb_name(cmd),
12551                                 (si->request)? "Request" : "Response");
12552                 }
12553
12554                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
12555                         "%s %s (0x%02x)",
12556                         decode_smb_name(cmd), 
12557                         (si->request)?"Request":"Response",
12558                         cmd);
12559
12560                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
12561
12562                 dissector = (si->request)?
12563                         smb_dissector[cmd].request:smb_dissector[cmd].response;
12564
12565                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
12566                 proto_item_set_len(cmd_item, offset-old_offset);
12567         }
12568         return offset;
12569 }
12570
12571
12572 /* NOTE: this value_string array will also be used to access data directly by
12573  * index instead of val_to_str() since 
12574  * 1, the array will always span every value from 0x00 to 0xff and
12575  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
12576  * This means that this value_string array MUST always
12577  * 1, contain all entries 0x00 to 0xff
12578  * 2, all entries must be in order.
12579  */
12580 static const value_string smb_cmd_vals[] = {
12581   { 0x00, "Create Directory" },
12582   { 0x01, "Delete Directory" },
12583   { 0x02, "Open" },
12584   { 0x03, "Create" },
12585   { 0x04, "Close" },
12586   { 0x05, "Flush" },
12587   { 0x06, "Delete" },
12588   { 0x07, "Rename" },
12589   { 0x08, "Query Information" },
12590   { 0x09, "Set Information" },
12591   { 0x0A, "Read" },
12592   { 0x0B, "Write" },
12593   { 0x0C, "Lock Byte Range" },
12594   { 0x0D, "Unlock Byte Range" },
12595   { 0x0E, "Create Temp" },
12596   { 0x0F, "Create New" },
12597   { 0x10, "Check Directory" },
12598   { 0x11, "Process Exit" },
12599   { 0x12, "Seek" },
12600   { 0x13, "Lock And Read" },
12601   { 0x14, "Write And Unlock" },
12602   { 0x15, "unknown-0x15" },
12603   { 0x16, "unknown-0x16" },
12604   { 0x17, "unknown-0x17" },
12605   { 0x18, "unknown-0x18" },
12606   { 0x19, "unknown-0x19" },
12607   { 0x1A, "Read Raw" },
12608   { 0x1B, "Read MPX" },
12609   { 0x1C, "Read MPX Secondary" },
12610   { 0x1D, "Write Raw" },
12611   { 0x1E, "Write MPX" },
12612   { 0x1F, "SMBwriteBs" },
12613   { 0x20, "Write Complete" },
12614   { 0x21, "unknown-0x21" },
12615   { 0x22, "Set Information2" },
12616   { 0x23, "Query Information2" },
12617   { 0x24, "Locking AndX" },
12618   { 0x25, "Transaction" },
12619   { 0x26, "Transaction Secondary" },
12620   { 0x27, "IOCTL" },
12621   { 0x28, "IOCTL Secondary" },
12622   { 0x29, "Copy" },
12623   { 0x2A, "Move" },
12624   { 0x2B, "Echo" },
12625   { 0x2C, "Write And Close" },
12626   { 0x2D, "Open AndX" },
12627   { 0x2E, "Read AndX" },
12628   { 0x2F, "Write AndX" },
12629   { 0x30, "unknown-0x30" },
12630   { 0x31, "Close And Tree Discover" },
12631   { 0x32, "Transaction2" },
12632   { 0x33, "Transaction2 Secondary" },
12633   { 0x34, "Find Close2" },
12634   { 0x35, "Find Notify Close" },
12635   { 0x36, "unknown-0x36" },
12636   { 0x37, "unknown-0x37" },
12637   { 0x38, "unknown-0x38" },
12638   { 0x39, "unknown-0x39" },
12639   { 0x3A, "unknown-0x3A" },
12640   { 0x3B, "unknown-0x3B" },
12641   { 0x3C, "unknown-0x3C" },
12642   { 0x3D, "unknown-0x3D" },
12643   { 0x3E, "unknown-0x3E" },
12644   { 0x3F, "unknown-0x3F" },
12645   { 0x40, "unknown-0x40" },
12646   { 0x41, "unknown-0x41" },
12647   { 0x42, "unknown-0x42" },
12648   { 0x43, "unknown-0x43" },
12649   { 0x44, "unknown-0x44" },
12650   { 0x45, "unknown-0x45" },
12651   { 0x46, "unknown-0x46" },
12652   { 0x47, "unknown-0x47" },
12653   { 0x48, "unknown-0x48" },
12654   { 0x49, "unknown-0x49" },
12655   { 0x4A, "unknown-0x4A" },
12656   { 0x4B, "unknown-0x4B" },
12657   { 0x4C, "unknown-0x4C" },
12658   { 0x4D, "unknown-0x4D" },
12659   { 0x4E, "unknown-0x4E" },
12660   { 0x4F, "unknown-0x4F" },
12661   { 0x50, "unknown-0x50" },
12662   { 0x51, "unknown-0x51" },
12663   { 0x52, "unknown-0x52" },
12664   { 0x53, "unknown-0x53" },
12665   { 0x54, "unknown-0x54" },
12666   { 0x55, "unknown-0x55" },
12667   { 0x56, "unknown-0x56" },
12668   { 0x57, "unknown-0x57" },
12669   { 0x58, "unknown-0x58" },
12670   { 0x59, "unknown-0x59" },
12671   { 0x5A, "unknown-0x5A" },
12672   { 0x5B, "unknown-0x5B" },
12673   { 0x5C, "unknown-0x5C" },
12674   { 0x5D, "unknown-0x5D" },
12675   { 0x5E, "unknown-0x5E" },
12676   { 0x5F, "unknown-0x5F" },
12677   { 0x60, "unknown-0x60" },
12678   { 0x61, "unknown-0x61" },
12679   { 0x62, "unknown-0x62" },
12680   { 0x63, "unknown-0x63" },
12681   { 0x64, "unknown-0x64" },
12682   { 0x65, "unknown-0x65" },
12683   { 0x66, "unknown-0x66" },
12684   { 0x67, "unknown-0x67" },
12685   { 0x68, "unknown-0x68" },
12686   { 0x69, "unknown-0x69" },
12687   { 0x6A, "unknown-0x6A" },
12688   { 0x6B, "unknown-0x6B" },
12689   { 0x6C, "unknown-0x6C" },
12690   { 0x6D, "unknown-0x6D" },
12691   { 0x6E, "unknown-0x6E" },
12692   { 0x6F, "unknown-0x6F" },
12693   { 0x70, "Tree Connect" },
12694   { 0x71, "Tree Disconnect" },
12695   { 0x72, "Negotiate Protocol" },
12696   { 0x73, "Session Setup AndX" },
12697   { 0x74, "Logoff AndX" },
12698   { 0x75, "Tree Connect AndX" },
12699   { 0x76, "unknown-0x76" },
12700   { 0x77, "unknown-0x77" },
12701   { 0x78, "unknown-0x78" },
12702   { 0x79, "unknown-0x79" },
12703   { 0x7A, "unknown-0x7A" },
12704   { 0x7B, "unknown-0x7B" },
12705   { 0x7C, "unknown-0x7C" },
12706   { 0x7D, "unknown-0x7D" },
12707   { 0x7E, "unknown-0x7E" },
12708   { 0x7F, "unknown-0x7F" },
12709   { 0x80, "Query Information Disk" },
12710   { 0x81, "Search" },
12711   { 0x82, "Find" },
12712   { 0x83, "Find Unique" },
12713   { 0x84, "SMBfclose" },
12714   { 0x85, "unknown-0x85" },
12715   { 0x86, "unknown-0x86" },
12716   { 0x87, "unknown-0x87" },
12717   { 0x88, "unknown-0x88" },
12718   { 0x89, "unknown-0x89" },
12719   { 0x8A, "unknown-0x8A" },
12720   { 0x8B, "unknown-0x8B" },
12721   { 0x8C, "unknown-0x8C" },
12722   { 0x8D, "unknown-0x8D" },
12723   { 0x8E, "unknown-0x8E" },
12724   { 0x8F, "unknown-0x8F" },
12725   { 0x90, "unknown-0x90" },
12726   { 0x91, "unknown-0x91" },
12727   { 0x92, "unknown-0x92" },
12728   { 0x93, "unknown-0x93" },
12729   { 0x94, "unknown-0x94" },
12730   { 0x95, "unknown-0x95" },
12731   { 0x96, "unknown-0x96" },
12732   { 0x97, "unknown-0x97" },
12733   { 0x98, "unknown-0x98" },
12734   { 0x99, "unknown-0x99" },
12735   { 0x9A, "unknown-0x9A" },
12736   { 0x9B, "unknown-0x9B" },
12737   { 0x9C, "unknown-0x9C" },
12738   { 0x9D, "unknown-0x9D" },
12739   { 0x9E, "unknown-0x9E" },
12740   { 0x9F, "unknown-0x9F" },
12741   { 0xA0, "NT Transact" },
12742   { 0xA1, "NT Transact Secondary" },
12743   { 0xA2, "NT Create AndX" },
12744   { 0xA3, "unknown-0xA3" },
12745   { 0xA4, "NT Cancel" },
12746   { 0xA5, "NT Rename" },
12747   { 0xA6, "unknown-0xA6" },
12748   { 0xA7, "unknown-0xA7" },
12749   { 0xA8, "unknown-0xA8" },
12750   { 0xA9, "unknown-0xA9" },
12751   { 0xAA, "unknown-0xAA" },
12752   { 0xAB, "unknown-0xAB" },
12753   { 0xAC, "unknown-0xAC" },
12754   { 0xAD, "unknown-0xAD" },
12755   { 0xAE, "unknown-0xAE" },
12756   { 0xAF, "unknown-0xAF" },
12757   { 0xB0, "unknown-0xB0" },
12758   { 0xB1, "unknown-0xB1" },
12759   { 0xB2, "unknown-0xB2" },
12760   { 0xB3, "unknown-0xB3" },
12761   { 0xB4, "unknown-0xB4" },
12762   { 0xB5, "unknown-0xB5" },
12763   { 0xB6, "unknown-0xB6" },
12764   { 0xB7, "unknown-0xB7" },
12765   { 0xB8, "unknown-0xB8" },
12766   { 0xB9, "unknown-0xB9" },
12767   { 0xBA, "unknown-0xBA" },
12768   { 0xBB, "unknown-0xBB" },
12769   { 0xBC, "unknown-0xBC" },
12770   { 0xBD, "unknown-0xBD" },
12771   { 0xBE, "unknown-0xBE" },
12772   { 0xBF, "unknown-0xBF" },
12773   { 0xC0, "Open Print File" },
12774   { 0xC1, "Write Print File" },
12775   { 0xC2, "Close Print File" },
12776   { 0xC3, "Get Print Queue" },
12777   { 0xC4, "unknown-0xC4" },
12778   { 0xC5, "unknown-0xC5" },
12779   { 0xC6, "unknown-0xC6" },
12780   { 0xC7, "unknown-0xC7" },
12781   { 0xC8, "unknown-0xC8" },
12782   { 0xC9, "unknown-0xC9" },
12783   { 0xCA, "unknown-0xCA" },
12784   { 0xCB, "unknown-0xCB" },
12785   { 0xCC, "unknown-0xCC" },
12786   { 0xCD, "unknown-0xCD" },
12787   { 0xCE, "unknown-0xCE" },
12788   { 0xCF, "unknown-0xCF" },
12789   { 0xD0, "SMBsends" },
12790   { 0xD1, "SMBsendb" },
12791   { 0xD2, "SMBfwdname" },
12792   { 0xD3, "SMBcancelf" },
12793   { 0xD4, "SMBgetmac" },
12794   { 0xD5, "SMBsendstrt" },
12795   { 0xD6, "SMBsendend" },
12796   { 0xD7, "SMBsendtxt" },
12797   { 0xD8, "SMBreadbulk" },
12798   { 0xD9, "SMBwritebulk" },
12799   { 0xDA, "SMBwritebulkdata" },
12800   { 0xDB, "unknown-0xDB" },
12801   { 0xDC, "unknown-0xDC" },
12802   { 0xDD, "unknown-0xDD" },
12803   { 0xDE, "unknown-0xDE" },
12804   { 0xDF, "unknown-0xDF" },
12805   { 0xE0, "unknown-0xE0" },
12806   { 0xE1, "unknown-0xE1" },
12807   { 0xE2, "unknown-0xE2" },
12808   { 0xE3, "unknown-0xE3" },
12809   { 0xE4, "unknown-0xE4" },
12810   { 0xE5, "unknown-0xE5" },
12811   { 0xE6, "unknown-0xE6" },
12812   { 0xE7, "unknown-0xE7" },
12813   { 0xE8, "unknown-0xE8" },
12814   { 0xE9, "unknown-0xE9" },
12815   { 0xEA, "unknown-0xEA" },
12816   { 0xEB, "unknown-0xEB" },
12817   { 0xEC, "unknown-0xEC" },
12818   { 0xED, "unknown-0xED" },
12819   { 0xEE, "unknown-0xEE" },
12820   { 0xEF, "unknown-0xEF" },
12821   { 0xF0, "unknown-0xF0" },
12822   { 0xF1, "unknown-0xF1" },
12823   { 0xF2, "unknown-0xF2" },
12824   { 0xF3, "unknown-0xF3" },
12825   { 0xF4, "unknown-0xF4" },
12826   { 0xF5, "unknown-0xF5" },
12827   { 0xF6, "unknown-0xF6" },
12828   { 0xF7, "unknown-0xF7" },
12829   { 0xF8, "unknown-0xF8" },
12830   { 0xF9, "unknown-0xF9" },
12831   { 0xFA, "unknown-0xFA" },
12832   { 0xFB, "unknown-0xFB" },
12833   { 0xFC, "unknown-0xFC" },
12834   { 0xFD, "unknown-0xFD" },
12835   { 0xFE, "SMBinvalid" },
12836   { 0xFF, "unknown-0xFF" },
12837   { 0x00, NULL },
12838 };
12839
12840 static char *decode_smb_name(unsigned char cmd)
12841 {
12842   return(smb_cmd_vals[cmd].strptr);
12843 }
12844  
12845
12846
12847 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
12848  * Everything TVBUFFIFIED above this line
12849  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
12850
12851
12852 static void
12853 free_hash_tables(gpointer ctarg, gpointer user_data)
12854 {
12855         conv_tables_t *ct = ctarg;
12856
12857         if (ct->unmatched)
12858                 g_hash_table_destroy(ct->unmatched);
12859         if (ct->matched)
12860                 g_hash_table_destroy(ct->matched);
12861         if (ct->dcerpc_fid_to_frame)
12862                 g_hash_table_destroy(ct->dcerpc_fid_to_frame);
12863         if (ct->tid_service)
12864                 g_hash_table_destroy(ct->tid_service);
12865 }
12866
12867 static void
12868 smb_init_protocol(void)
12869 {
12870         if (smb_saved_info_key_chunk)
12871                 g_mem_chunk_destroy(smb_saved_info_key_chunk);
12872         if (smb_saved_info_chunk)
12873                 g_mem_chunk_destroy(smb_saved_info_chunk);
12874         if (smb_nt_transact_info_chunk)
12875                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
12876         if (smb_transact2_info_chunk)
12877                 g_mem_chunk_destroy(smb_transact2_info_chunk);
12878         if (smb_transact_info_chunk)
12879                 g_mem_chunk_destroy(smb_transact_info_chunk);
12880
12881         /*
12882          * Free the hash tables attached to the conversation table
12883          * structures, and then free the list of conversation table
12884          * data structures (which doesn't free the data structures
12885          * themselves; that's done by destroying the chunk from
12886          * which they were allocated).
12887          */
12888         if (conv_tables) {
12889                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
12890                 g_slist_free(conv_tables);
12891                 conv_tables = NULL;
12892         }
12893
12894         /*
12895          * Now destroy the chunk from which the conversation table
12896          * structures were allocated.
12897          */
12898         if (conv_tables_chunk)
12899                 g_mem_chunk_destroy(conv_tables_chunk);
12900
12901         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
12902             sizeof(smb_saved_info_t),
12903             smb_saved_info_init_count * sizeof(smb_saved_info_t),
12904             G_ALLOC_ONLY);
12905         smb_saved_info_key_chunk = g_mem_chunk_new("smb_saved_info_key_chunk",
12906             sizeof(smb_saved_info_key_t),
12907             smb_saved_info_init_count * sizeof(smb_saved_info_key_t),
12908             G_ALLOC_ONLY);
12909         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
12910             sizeof(smb_nt_transact_info_t),
12911             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
12912             G_ALLOC_ONLY);
12913         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
12914             sizeof(smb_transact2_info_t),
12915             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
12916             G_ALLOC_ONLY);
12917         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
12918             sizeof(smb_transact_info_t),
12919             smb_transact_info_init_count * sizeof(smb_transact_info_t),
12920             G_ALLOC_ONLY);
12921         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
12922             sizeof(conv_tables_t),
12923             conv_tables_count * sizeof(conv_tables_t),
12924             G_ALLOC_ONLY);
12925 }
12926
12927 /* Max string length for displaying Unicode strings.  */
12928 #define MAX_UNICODE_STR_LEN     256
12929
12930
12931 /* Turn a little-endian Unicode '\0'-terminated string into a string we
12932    can display.
12933    XXX - for now, we just handle the ISO 8859-1 characters.
12934    If exactlen==TRUE then us_lenp contains the exact len of the string in
12935    bytes. It might not be null terminated !
12936    bc specifies the number of bytes in the byte parameters; Windows 2000,
12937    at least, appears, in some cases, to put only 1 byte of 0 at the end
12938    of a Unicode string if the byte count
12939 */
12940 static gchar *
12941 unicode_to_str(tvbuff_t *tvb, int offset, int *us_lenp, gboolean exactlen,
12942                    guint16 bc)
12943 {
12944   static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
12945   static gchar *cur;
12946   gchar        *p;
12947   guint16       uchar;
12948   int           len;
12949   int           us_len;
12950   int           overflow = 0;
12951
12952   if (cur == &str[0][0]) {
12953     cur = &str[1][0];
12954   } else if (cur == &str[1][0]) {  
12955     cur = &str[2][0];
12956   } else {  
12957     cur = &str[0][0];
12958   }
12959   p = cur;
12960   len = MAX_UNICODE_STR_LEN;
12961   us_len = 0;
12962   for (;;) {
12963     if (bc == 0)
12964       break;
12965     if (bc == 1) {
12966       /* XXX - explain this */
12967       if (!exactlen)
12968         us_len += 1;    /* this is a one-byte null terminator */
12969       break;
12970     }
12971     uchar = tvb_get_letohs(tvb, offset);
12972     if (uchar == 0) {
12973       us_len += 2;      /* this is a two-byte null terminator */
12974       break;
12975     }
12976     if (len > 0) {
12977       if ((uchar & 0xFF00) == 0)
12978         *p++ = uchar;   /* ISO 8859-1 */
12979       else
12980         *p++ = '?';     /* not 8859-1 */
12981       len--;
12982     } else
12983       overflow = 1;
12984     offset += 2;
12985     bc -= 2;
12986     us_len += 2;
12987     if(exactlen){
12988       if(us_len>= *us_lenp){
12989         break;
12990       }
12991     }
12992   }
12993   if (overflow) {
12994     /* Note that we're not showing the full string.  */
12995     *p++ = '.';
12996     *p++ = '.';
12997     *p++ = '.';
12998   }
12999   *p = '\0';
13000   *us_lenp = us_len;
13001   return cur;
13002 }
13003  
13004
13005 /* nopad == TRUE : Do not add any padding before this string
13006  * exactlen == TRUE : len contains the exact len of the string in bytes.
13007  * bc: pointer to variable with amount of data left in the byte parameters
13008  *   region
13009  */
13010 static const gchar *
13011 get_unicode_or_ascii_string(tvbuff_t *tvb, int *offsetp,
13012     packet_info *pinfo, int *len, gboolean nopad, gboolean exactlen,
13013     guint16 *bcp)
13014 {
13015   static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
13016   static gchar *cur;
13017   const gchar *string;
13018   int string_len;
13019   smb_info_t *si;
13020   unsigned int copylen;
13021
13022   if (*bcp == 0) {
13023     /* Not enough data in buffer */
13024     return NULL;
13025   }
13026   si = pinfo->private_data;
13027   if (si->unicode) {
13028     if ((!nopad) && (*offsetp % 2)) {
13029       /*
13030        * XXX - this should be an offset relative to the beginning of the SMB,
13031        * not an offset relative to the beginning of the frame; if the stuff
13032        * before the SMB has an odd number of bytes, an offset relative to
13033        * the beginning of the frame will give the wrong answer.
13034        */
13035       (*offsetp)++;   /* Looks like a pad byte there sometimes */
13036       (*bcp)--;
13037       if (*bcp == 0) {
13038         /* Not enough data in buffer */
13039         return NULL;
13040       }
13041     }
13042     if(exactlen){
13043       string_len = *len;
13044       string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
13045     } else {
13046       string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
13047     }
13048   } else {
13049     if(exactlen){
13050       /*
13051        * The string we return must be null-terminated.
13052        */
13053       if (cur == &str[0][0]) {
13054         cur = &str[1][0];
13055       } else if (cur == &str[1][0]) {  
13056         cur = &str[2][0];
13057       } else {  
13058         cur = &str[0][0];
13059       }
13060       copylen = *len;
13061       if (copylen > MAX_UNICODE_STR_LEN)
13062         copylen = MAX_UNICODE_STR_LEN;
13063       tvb_memcpy(tvb, (guint8 *)cur, *offsetp, copylen);
13064       cur[copylen] = '\0';
13065       if (copylen > MAX_UNICODE_STR_LEN)
13066         strcat(cur, "...");
13067       string_len = *len;
13068       string = cur;
13069     } else {
13070       string_len = tvb_strsize(tvb, *offsetp);
13071       string = tvb_get_ptr(tvb, *offsetp, string_len);
13072     }
13073   }
13074   *len = string_len;
13075   return string;
13076 }
13077
13078
13079
13080 static const value_string errcls_types[] = {
13081   { SMB_SUCCESS, "Success"},
13082   { SMB_ERRDOS, "DOS Error"},
13083   { SMB_ERRSRV, "Server Error"},
13084   { SMB_ERRHRD, "Hardware Error"},
13085   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
13086   { 0, NULL }
13087 };
13088
13089 const value_string DOS_errors[] = {
13090   {0, "Success"},
13091   {SMBE_insufficientbuffer, "Insufficient buffer"},
13092   {SMBE_badfunc, "Invalid function (or system call)"},
13093   {SMBE_badfile, "File not found (pathname error)"},
13094   {SMBE_badpath, "Directory not found"},
13095   {SMBE_nofids, "Too many open files"},
13096   {SMBE_noaccess, "Access denied"},
13097   {SMBE_badfid, "Invalid fid"},
13098   {SMBE_nomem,  "Out of memory"},
13099   {SMBE_badmem, "Invalid memory block address"},
13100   {SMBE_badenv, "Invalid environment"},
13101   {SMBE_badaccess, "Invalid open mode"},
13102   {SMBE_baddata, "Invalid data (only from ioctl call)"},
13103   {SMBE_res, "Reserved error code?"}, 
13104   {SMBE_baddrive, "Invalid drive"},
13105   {SMBE_remcd, "Attempt to delete current directory"},
13106   {SMBE_diffdevice, "Rename/move across different filesystems"},
13107   {SMBE_nofiles, "No more files found in file search"},
13108   {SMBE_badshare, "Share mode on file conflict with open mode"},
13109   {SMBE_lock, "Lock request conflicts with existing lock"},
13110   {SMBE_unsup, "Request unsupported, returned by Win 95"},
13111   {SMBE_nosuchshare, "Requested share does not exist"},
13112   {SMBE_filexists, "File in operation already exists"},
13113   {SMBE_cannotopen, "Cannot open the file specified"},
13114   {SMBE_unknownlevel, "Unknown info level"},
13115   {SMBE_invalidname, "Invalid name"},
13116   {SMBE_badpipe, "Named pipe invalid"},
13117   {SMBE_pipebusy, "All instances of pipe are busy"},
13118   {SMBE_pipeclosing, "Named pipe close in progress"},
13119   {SMBE_notconnected, "No process on other end of named pipe"},
13120   {SMBE_moredata, "More data to be returned"},
13121   {SMBE_baddirectory,  "Invalid directory name in a path."},
13122   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
13123   {SMBE_eas_nsup, "Extended attributes not supported"},
13124   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
13125   {SMBE_unknownipc, "Unknown IPC Operation"},
13126   {SMBE_noipc, "Don't support ipc"},
13127   {SMBE_alreadyexists, "File already exists"},
13128   {SMBE_unknownprinterdriver, "Unknown printer driver"},
13129   {SMBE_invalidprintername, "Invalid printer name"},
13130   {SMBE_printeralreadyexists, "Printer already exists"},
13131   {SMBE_invaliddatatype, "Invalid data type"},
13132   {SMBE_invalidenvironment, "Invalid environment"},
13133   {SMBE_printerdriverinuse, "Printer driver in use"},
13134   {SMBE_invalidparam, "Invalid parameter"},
13135   {SMBE_invalidformsize, "Invalid form size"},
13136   {SMBE_invalidsecuritydescriptor, "Invalid security descriptor"},
13137   {0, NULL}
13138   };
13139
13140 /* Error codes for the ERRSRV class */
13141
13142 static const value_string SRV_errors[] = {
13143   {SMBE_error, "Non specific error code"},
13144   {SMBE_badpw, "Bad password"},
13145   {SMBE_badtype, "Reserved"},
13146   {SMBE_access, "No permissions to perform the requested operation"},
13147   {SMBE_invnid, "TID invalid"},
13148   {SMBE_invnetname, "Invalid network name. Service not found"},
13149   {SMBE_invdevice, "Invalid device"},
13150   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
13151   {SMBE_qfull, "Print queue full"},
13152   {SMBE_qtoobig, "Queued item too big"},
13153   {SMBE_qeof, "EOF on print queue dump"},
13154   {SMBE_invpfid, "Invalid print file in smb_fid"},
13155   {SMBE_smbcmd, "Unrecognised command"},
13156   {SMBE_srverror, "SMB server internal error"},
13157   {SMBE_filespecs, "Fid and pathname invalid combination"},
13158   {SMBE_badlink, "Bad link in request ???"},
13159   {SMBE_badpermits, "Access specified for a file is not valid"},
13160   {SMBE_badpid, "Bad process id in request"},
13161   {SMBE_setattrmode, "Attribute mode invalid"},
13162   {SMBE_paused, "Message server paused"},
13163   {SMBE_msgoff, "Not receiving messages"},
13164   {SMBE_noroom, "No room for message"},
13165   {SMBE_rmuns, "Too many remote usernames"},
13166   {SMBE_timeout, "Operation timed out"},
13167   {SMBE_noresource, "No resources currently available for request."},
13168   {SMBE_toomanyuids, "Too many userids"},
13169   {SMBE_baduid, "Bad userid"},
13170   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
13171   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
13172   {SMBE_contMPX, "Resume MPX mode"},
13173   {SMBE_badPW, "Bad Password???"},
13174   {SMBE_nosupport, "Operation not supported"},
13175   { 0, NULL}
13176 };
13177
13178 /* Error codes for the ERRHRD class */
13179
13180 static const value_string HRD_errors[] = {
13181   {SMBE_nowrite, "Read only media"},
13182   {SMBE_badunit, "Unknown device"},
13183   {SMBE_notready, "Drive not ready"},
13184   {SMBE_badcmd, "Unknown command"},
13185   {SMBE_data, "Data (CRC) error"},
13186   {SMBE_badreq, "Bad request structure length"},
13187   {SMBE_seek, "Seek error???"},
13188   {SMBE_badmedia, "Bad media???"},
13189   {SMBE_badsector, "Bad sector???"},
13190   {SMBE_nopaper, "No paper in printer???"},
13191   {SMBE_write, "Write error???"},
13192   {SMBE_read, "Read error???"},
13193   {SMBE_general, "General error???"},
13194   {SMBE_badshare, "A open conflicts with an existing open"},
13195   {SMBE_lock, "Lock/unlock error"},
13196   {SMBE_wrongdisk,  "Wrong disk???"},
13197   {SMBE_FCBunavail, "FCB unavailable???"},
13198   {SMBE_sharebufexc, "Share buffer excluded???"},
13199   {SMBE_diskfull, "Disk full???"},
13200   {0, NULL}
13201 };
13202
13203 static char *decode_smb_error(guint8 errcls, guint16 errcode)
13204 {
13205
13206   switch (errcls) {
13207
13208   case SMB_SUCCESS:
13209
13210     return("No Error");   /* No error ??? */
13211     break;
13212
13213   case SMB_ERRDOS:
13214
13215     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
13216     break;
13217
13218   case SMB_ERRSRV:
13219
13220     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
13221     break;
13222
13223   case SMB_ERRHRD:
13224
13225     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
13226     break;
13227
13228   default:
13229
13230     return("Unknown error class!");
13231
13232   }
13233
13234 }
13235
13236
13237 /* These are the MS country codes from
13238
13239         http://www.unicode.org/unicode/onlinedat/countries.html
13240
13241    For countries that share the same number, I choose to use only the
13242    name of the largest country. Apologies for this. If this offends you,
13243    here is the table to change that.
13244
13245    This also includes the code of 0 for "Default", which isn't in
13246    that list, but is in Microsoft's SDKs and the Cygnus "winnls.h"
13247    header file.  Presumably it means "don't override the setting
13248    on the user's machine".
13249
13250    Future versions of Microsoft's "winnls.h" header file might include
13251    additional codes; the current version matches the Unicode Consortium's
13252    table.
13253 */
13254 const value_string ms_country_codes[] = {
13255         {  0,   "Default"},
13256         {  1,   "USA"},
13257         {  2,   "Canada"},
13258         {  7,   "Russia"},
13259         { 20,   "Egypt"},
13260         { 27,   "South Africa"},
13261         { 30,   "Greece"},
13262         { 31,   "Netherlands"},
13263         { 32,   "Belgium"},
13264         { 33,   "France"},
13265         { 34,   "Spain"},
13266         { 36,   "Hungary"},
13267         { 39,   "Italy"},
13268         { 40,   "Romania"},
13269         { 41,   "Switzerland"},
13270         { 43,   "Austria"},
13271         { 44,   "United Kingdom"},
13272         { 45,   "Denmark"},
13273         { 46,   "Sweden"},
13274         { 47,   "Norway"},
13275         { 48,   "Poland"},
13276         { 49,   "Germany"},
13277         { 51,   "Peru"},
13278         { 52,   "Mexico"},
13279         { 54,   "Argentina"},
13280         { 55,   "Brazil"},
13281         { 56,   "Chile"},
13282         { 57,   "Colombia"},
13283         { 58,   "Venezuela"},
13284         { 60,   "Malaysia"},
13285         { 61,   "Australia"},
13286         { 62,   "Indonesia"},
13287         { 63,   "Philippines"},
13288         { 64,   "New Zealand"},
13289         { 65,   "Singapore"},
13290         { 66,   "Thailand"},
13291         { 81,   "Japan"},
13292         { 82,   "South Korea"},
13293         { 84,   "Viet Nam"},
13294         { 86,   "China"},
13295         { 90,   "Turkey"},
13296         { 91,   "India"},
13297         { 92,   "Pakistan"},
13298         {212,   "Morocco"},
13299         {213,   "Algeria"},
13300         {216,   "Tunisia"},
13301         {218,   "Libya"},
13302         {254,   "Kenya"},
13303         {263,   "Zimbabwe"},
13304         {298,   "Faroe Islands"},
13305         {351,   "Portugal"},
13306         {352,   "Luxembourg"},
13307         {353,   "Ireland"},
13308         {354,   "Iceland"},
13309         {355,   "Albania"},
13310         {358,   "Finland"},
13311         {359,   "Bulgaria"},
13312         {370,   "Lithuania"},
13313         {371,   "Latvia"},
13314         {372,   "Estonia"},
13315         {374,   "Armenia"},
13316         {375,   "Belarus"},
13317         {380,   "Ukraine"},
13318         {381,   "Serbia"},
13319         {385,   "Croatia"},
13320         {386,   "Slovenia"},
13321         {389,   "Macedonia"},
13322         {420,   "Czech Republic"},
13323         {421,   "Slovak Republic"},
13324         {501,   "Belize"},
13325         {502,   "Guatemala"},
13326         {503,   "El Salvador"},
13327         {504,   "Honduras"},
13328         {505,   "Nicaragua"},
13329         {506,   "Costa Rica"},
13330         {507,   "Panama"},
13331         {591,   "Bolivia"},
13332         {593,   "Ecuador"},
13333         {595,   "Paraguay"},
13334         {598,   "Uruguay"},
13335         {673,   "Brunei Darussalam"},
13336         {852,   "Hong Kong"},
13337         {853,   "Macau"},
13338         {886,   "Taiwan"},
13339         {960,   "Maldives"},
13340         {961,   "Lebanon"},
13341         {962,   "Jordan"},
13342         {963,   "Syria"},
13343         {964,   "Iraq"},
13344         {965,   "Kuwait"},
13345         {966,   "Saudi Arabia"},
13346         {967,   "Yemen"},
13347         {968,   "Oman"},
13348         {971,   "United Arab Emirates"},
13349         {972,   "Israel"},
13350         {973,   "Bahrain"},
13351         {974,   "Qatar"},
13352         {976,   "Mongolia"},
13353         {981,   "Iran"},
13354         {994,   "Azerbaijan"},
13355         {995,   "Georgia"},
13356         {996,   "Kyrgyzstan"},
13357
13358         {0,     NULL}
13359 };
13360
13361 /*
13362  * NT error codes.
13363  *
13364  * From
13365  *
13366  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
13367  */
13368 const value_string NT_errors[] = {
13369   { 0x00000000, "STATUS_SUCCESS" },
13370   { 0x00000000, "STATUS_WAIT_0" },
13371   { 0x00000001, "STATUS_WAIT_1" },
13372   { 0x00000002, "STATUS_WAIT_2" },
13373   { 0x00000003, "STATUS_WAIT_3" },
13374   { 0x0000003F, "STATUS_WAIT_63" },
13375   { 0x00000080, "STATUS_ABANDONED" },
13376   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
13377   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
13378   { 0x000000C0, "STATUS_USER_APC" },
13379   { 0x00000100, "STATUS_KERNEL_APC" },
13380   { 0x00000101, "STATUS_ALERTED" },
13381   { 0x00000102, "STATUS_TIMEOUT" },
13382   { 0x00000103, "STATUS_PENDING" },
13383   { 0x00000104, "STATUS_REPARSE" },
13384   { 0x00000105, "STATUS_MORE_ENTRIES" },
13385   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
13386   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
13387   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
13388   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
13389   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
13390   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
13391   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
13392   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
13393   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
13394   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
13395   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
13396   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
13397   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
13398   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
13399   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
13400   { 0x00000116, "STATUS_CRASH_DUMP" },
13401   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
13402   { 0x00000118, "STATUS_REPARSE_OBJECT" },
13403   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
13404   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
13405   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
13406   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
13407   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
13408   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
13409   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
13410   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
13411   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
13412   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
13413   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
13414   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
13415   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
13416   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
13417   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
13418   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
13419   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
13420   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
13421   { 0x40000012, "STATUS_EVENT_DONE" },
13422   { 0x40000013, "STATUS_EVENT_PENDING" },
13423   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
13424   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
13425   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
13426   { 0x40000017, "STATUS_WAS_UNLOCKED" },
13427   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
13428   { 0x40000019, "STATUS_WAS_LOCKED" },
13429   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
13430   { 0x4000001B, "STATUS_ALREADY_WIN32" },
13431   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
13432   { 0x4000001D, "STATUS_WX86_CONTINUE" },
13433   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
13434   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
13435   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
13436   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
13437   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
13438   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
13439   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
13440   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
13441   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
13442   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
13443   { 0x80000003, "STATUS_BREAKPOINT" },
13444   { 0x80000004, "STATUS_SINGLE_STEP" },
13445   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
13446   { 0x80000006, "STATUS_NO_MORE_FILES" },
13447   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
13448   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
13449   { 0x8000000B, "STATUS_NO_INHERITANCE" },
13450   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
13451   { 0x8000000D, "STATUS_PARTIAL_COPY" },
13452   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
13453   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
13454   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
13455   { 0x80000011, "STATUS_DEVICE_BUSY" },
13456   { 0x80000012, "STATUS_NO_MORE_EAS" },
13457   { 0x80000013, "STATUS_INVALID_EA_NAME" },
13458   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
13459   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
13460   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
13461   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
13462   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
13463   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
13464   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
13465   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
13466   { 0x8000001D, "STATUS_BUS_RESET" },
13467   { 0x8000001E, "STATUS_END_OF_MEDIA" },
13468   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
13469   { 0x80000020, "STATUS_MEDIA_CHECK" },
13470   { 0x80000021, "STATUS_SETMARK_DETECTED" },
13471   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
13472   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
13473   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
13474   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
13475   { 0x80000026, "STATUS_LONGJUMP" },
13476   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
13477   { 0x80090301, "SEC_E_INVALID_HANDLE" },
13478   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
13479   { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
13480   { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
13481   { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
13482   { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
13483   { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
13484   { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
13485   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
13486   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
13487   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
13488   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
13489   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
13490   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
13491   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
13492   { 0xC0000008, "STATUS_INVALID_HANDLE" },
13493   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
13494   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
13495   { 0xC000000B, "STATUS_INVALID_CID" },
13496   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
13497   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
13498   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
13499   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
13500   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
13501   { 0xC0000011, "STATUS_END_OF_FILE" },
13502   { 0xC0000012, "STATUS_WRONG_VOLUME" },
13503   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
13504   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
13505   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
13506   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
13507   { 0xC0000017, "STATUS_NO_MEMORY" },
13508   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
13509   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
13510   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
13511   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
13512   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
13513   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
13514   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
13515   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
13516   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
13517   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
13518   { 0xC0000022, "STATUS_ACCESS_DENIED" },
13519   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
13520   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
13521   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
13522   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
13523   { 0xC0000027, "STATUS_UNWIND" },
13524   { 0xC0000028, "STATUS_BAD_STACK" },
13525   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
13526   { 0xC000002A, "STATUS_NOT_LOCKED" },
13527   { 0xC000002B, "STATUS_PARITY_ERROR" },
13528   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
13529   { 0xC000002D, "STATUS_NOT_COMMITTED" },
13530   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
13531   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
13532   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
13533   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
13534   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
13535   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
13536   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
13537   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
13538   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
13539   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
13540   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
13541   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
13542   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
13543   { 0xC000003C, "STATUS_DATA_OVERRUN" },
13544   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
13545   { 0xC000003E, "STATUS_DATA_ERROR" },
13546   { 0xC000003F, "STATUS_CRC_ERROR" },
13547   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
13548   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
13549   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
13550   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
13551   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
13552   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
13553   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
13554   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
13555   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
13556   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
13557   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
13558   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
13559   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
13560   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
13561   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
13562   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
13563   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
13564   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
13565   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
13566   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
13567   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
13568   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
13569   { 0xC0000056, "STATUS_DELETE_PENDING" },
13570   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
13571   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
13572   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
13573   { 0xC000005A, "STATUS_INVALID_OWNER" },
13574   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
13575   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
13576   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
13577   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
13578   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
13579   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
13580   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
13581   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
13582   { 0xC0000063, "STATUS_USER_EXISTS" },
13583   { 0xC0000064, "STATUS_NO_SUCH_USER" },
13584   { 0xC0000065, "STATUS_GROUP_EXISTS" },
13585   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
13586   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
13587   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
13588   { 0xC0000069, "STATUS_LAST_ADMIN" },
13589   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
13590   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
13591   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
13592   { 0xC000006D, "STATUS_LOGON_FAILURE" },
13593   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
13594   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
13595   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
13596   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
13597   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
13598   { 0xC0000073, "STATUS_NONE_MAPPED" },
13599   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
13600   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
13601   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
13602   { 0xC0000077, "STATUS_INVALID_ACL" },
13603   { 0xC0000078, "STATUS_INVALID_SID" },
13604   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
13605   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
13606   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
13607   { 0xC000007C, "STATUS_NO_TOKEN" },
13608   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
13609   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
13610   { 0xC000007F, "STATUS_DISK_FULL" },
13611   { 0xC0000080, "STATUS_SERVER_DISABLED" },
13612   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
13613   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
13614   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
13615   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
13616   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
13617   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
13618   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
13619   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
13620   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
13621   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
13622   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
13623   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
13624   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
13625   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
13626   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
13627   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
13628   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
13629   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
13630   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
13631   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
13632   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
13633   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
13634   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
13635   { 0xC0000098, "STATUS_FILE_INVALID" },
13636   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
13637   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
13638   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
13639   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
13640   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
13641   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
13642   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
13643   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
13644   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
13645   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
13646   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
13647   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
13648   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
13649   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
13650   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
13651   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
13652   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
13653   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
13654   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
13655   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
13656   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
13657   { 0xC00000AE, "STATUS_PIPE_BUSY" },
13658   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
13659   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
13660   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
13661   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
13662   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
13663   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
13664   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
13665   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
13666   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
13667   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
13668   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
13669   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
13670   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
13671   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
13672   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
13673   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
13674   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
13675   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
13676   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
13677   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
13678   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
13679   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
13680   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
13681   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
13682   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
13683   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
13684   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
13685   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
13686   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
13687   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
13688   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
13689   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
13690   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
13691   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
13692   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
13693   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
13694   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
13695   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
13696   { 0xC00000D5, "STATUS_FILE_RENAMED" },
13697   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
13698   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
13699   { 0xC00000D8, "STATUS_CANT_WAIT" },
13700   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
13701   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
13702   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
13703   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
13704   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
13705   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
13706   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
13707   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
13708   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
13709   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
13710   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
13711   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
13712   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
13713   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
13714   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
13715   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
13716   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
13717   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
13718   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
13719   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
13720   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
13721   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
13722   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
13723   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
13724   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
13725   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
13726   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
13727   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
13728   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
13729   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
13730   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
13731   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
13732   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
13733   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
13734   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
13735   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
13736   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
13737   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
13738   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
13739   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
13740   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
13741   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
13742   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
13743   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
13744   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
13745   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
13746   { 0xC0000107, "STATUS_FILES_OPEN" },
13747   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
13748   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
13749   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
13750   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
13751   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
13752   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
13753   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
13754   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
13755   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
13756   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
13757   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
13758   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
13759   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
13760   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
13761   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
13762   { 0xC0000117, "STATUS_NO_LDT" },
13763   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
13764   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
13765   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
13766   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
13767   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
13768   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
13769   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
13770   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
13771   { 0xC0000120, "STATUS_CANCELLED" },
13772   { 0xC0000121, "STATUS_CANNOT_DELETE" },
13773   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
13774   { 0xC0000123, "STATUS_FILE_DELETED" },
13775   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
13776   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
13777   { 0xC0000126, "STATUS_SPECIAL_USER" },
13778   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
13779   { 0xC0000128, "STATUS_FILE_CLOSED" },
13780   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
13781   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
13782   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
13783   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
13784   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
13785   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
13786   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
13787   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
13788   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
13789   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
13790   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
13791   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
13792   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
13793   { 0xC0000136, "STATUS_OPEN_FAILED" },
13794   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
13795   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
13796   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
13797   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
13798   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
13799   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
13800   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
13801   { 0xC000013E, "STATUS_LINK_FAILED" },
13802   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
13803   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
13804   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
13805   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
13806   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
13807   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
13808   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
13809   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
13810   { 0xC0000147, "STATUS_NO_PAGEFILE" },
13811   { 0xC0000148, "STATUS_INVALID_LEVEL" },
13812   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
13813   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
13814   { 0xC000014B, "STATUS_PIPE_BROKEN" },
13815   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
13816   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
13817   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
13818   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
13819   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
13820   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
13821   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
13822   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
13823   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
13824   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
13825   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
13826   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
13827   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
13828   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
13829   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
13830   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
13831   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
13832   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
13833   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
13834   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
13835   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
13836   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
13837   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
13838   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
13839   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
13840   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
13841   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
13842   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
13843   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
13844   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
13845   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
13846   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
13847   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
13848   { 0xC000016D, "STATUS_FT_ORPHANING" },
13849   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
13850   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
13851   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
13852   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
13853   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
13854   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
13855   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
13856   { 0xC0000178, "STATUS_NO_MEDIA" },
13857   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
13858   { 0xC000017B, "STATUS_INVALID_MEMBER" },
13859   { 0xC000017C, "STATUS_KEY_DELETED" },
13860   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
13861   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
13862   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
13863   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
13864   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
13865   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
13866   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
13867   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
13868   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
13869   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
13870   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
13871   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
13872   { 0xC0000189, "STATUS_TOO_LATE" },
13873   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
13874   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
13875   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
13876   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
13877   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
13878   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
13879   { 0xC0000190, "STATUS_TRUST_FAILURE" },
13880   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
13881   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
13882   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
13883   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
13884   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
13885   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
13886   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
13887   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
13888   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
13889   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
13890   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
13891   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
13892   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
13893   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
13894   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
13895   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
13896   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
13897   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
13898   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
13899   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
13900   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
13901   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
13902   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
13903   { 0xC000020D, "STATUS_CONNECTION_RESET" },
13904   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
13905   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
13906   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
13907   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
13908   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
13909   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
13910   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
13911   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
13912   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
13913   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
13914   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
13915   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
13916   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
13917   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
13918   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
13919   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
13920   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
13921   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
13922   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
13923   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
13924   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
13925   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
13926   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
13927   { 0xC0000225, "STATUS_NOT_FOUND" },
13928   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
13929   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
13930   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
13931   { 0xC0000229, "STATUS_FAIL_CHECK" },
13932   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
13933   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
13934   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
13935   { 0xC000022D, "STATUS_RETRY" },
13936   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
13937   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
13938   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
13939   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
13940   { 0xC0000232, "STATUS_INVALID_VARIANT" },
13941   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
13942   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
13943   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
13944   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
13945   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
13946   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
13947   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
13948   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
13949   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
13950   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
13951   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
13952   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
13953   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
13954   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
13955   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
13956   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
13957   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
13958   { 0xC0000244, "STATUS_AUDIT_FAILED" },
13959   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
13960   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
13961   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
13962   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
13963   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
13964   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
13965   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
13966   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
13967   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
13968   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
13969   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
13970   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
13971   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
13972   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
13973   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
13974   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
13975   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
13976   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
13977   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
13978   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
13979   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
13980   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
13981   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
13982   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
13983   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
13984   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
13985   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
13986   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
13987   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
13988   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
13989   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
13990   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
13991   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
13992   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
13993   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
13994   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
13995   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
13996   { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
13997   { 0xC0000272, "STATUS_NO_MATCH" },
13998   { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
13999   { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
14000   { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
14001   { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
14002   { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
14003   { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
14004   { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
14005   { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
14006   { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
14007   { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
14008   { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
14009   { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
14010   { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
14011   { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
14012   { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
14013   { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
14014   { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
14015   { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
14016   { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
14017   { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
14018   { 0xC000028E, "STATUS_NO_EFS" },
14019   { 0xC000028F, "STATUS_WRONG_EFS" },
14020   { 0xC0000290, "STATUS_NO_USER_KEYS" },
14021   { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
14022   { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
14023   { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
14024   { 0x40000294, "STATUS_WAKE_SYSTEM" },
14025   { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
14026   { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
14027   { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
14028   { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
14029   { 0xC0000299, "STATUS_SHARED_POLICY" },
14030   { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
14031   { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
14032   { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
14033   { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
14034   { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
14035   { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
14036   { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
14037   { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
14038   { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
14039   { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
14040   { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
14041   { 0xC00002A5, "STATUS_DS_BUSY" },
14042   { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
14043   { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
14044   { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
14045   { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
14046   { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
14047   { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
14048   { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
14049   { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
14050   { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
14051   { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
14052   { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
14053   { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
14054   { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
14055   { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
14056   { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
14057   { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
14058   { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
14059   { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
14060   { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
14061   { 0xC00002B9, "STATUS_NOINTERFACE" },
14062   { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
14063   { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
14064   { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
14065   { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
14066   { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
14067   { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
14068   { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
14069   { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
14070   { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
14071   { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
14072   { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
14073   { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
14074   { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
14075   { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
14076   { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
14077   { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
14078   { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
14079   { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
14080   { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
14081   { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
14082   { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
14083   { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
14084   { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
14085   { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
14086   { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
14087   { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
14088   { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
14089   { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
14090   { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
14091   { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
14092   { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
14093   { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
14094   { 0xC00002E1, "STATUS_DS_CANT_START" },
14095   { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
14096   { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
14097   { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
14098   { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
14099   { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
14100   { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
14101   { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
14102   { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
14103   { 0xC0009898, "STATUS_WOW_ASSERTION" },
14104   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
14105   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
14106   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
14107   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
14108   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
14109   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
14110   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
14111   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
14112   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
14113   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
14114   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
14115   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
14116   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
14117   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
14118   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
14119   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
14120   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
14121   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
14122   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
14123   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
14124   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
14125   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
14126   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
14127   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
14128   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
14129   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
14130   { 0xC002001B, "RPC_NT_CALL_FAILED" },
14131   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
14132   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
14133   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
14134   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
14135   { 0xC0020022, "RPC_NT_INVALID_TAG" },
14136   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
14137   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
14138   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
14139   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
14140   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
14141   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
14142   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
14143   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
14144   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
14145   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
14146   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
14147   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
14148   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
14149   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
14150   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
14151   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
14152   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
14153   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
14154   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
14155   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
14156   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
14157   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
14158   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
14159   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
14160   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
14161   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
14162   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
14163   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
14164   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
14165   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
14166   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
14167   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
14168   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
14169   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
14170   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
14171   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
14172   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
14173   { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
14174   { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
14175   { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
14176   { 0xC002100A, "RPC_P_SEND_FAILED" },
14177   { 0xC002100B, "RPC_P_TIMEOUT" },
14178   { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
14179   { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
14180   { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
14181   { 0xC0021015, "RPC_P_THREAD_LISTENING" },
14182   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
14183   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
14184   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
14185   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
14186   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
14187   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
14188   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
14189   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
14190   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
14191   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
14192   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
14193   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
14194   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
14195   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
14196   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
14197   { 0xC002004C, "EPT_NT_CANT_CREATE" },
14198   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
14199   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
14200   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
14201   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
14202   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
14203   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
14204   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
14205   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
14206   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
14207   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
14208   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
14209   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
14210   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
14211   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
14212   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
14213   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
14214   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
14215   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
14216   { 0,          NULL }
14217 };
14218
14219
14220
14221 static const true_false_string tfs_smb_flags_lock = {
14222         "Lock&Read, Write&Unlock are supported",
14223         "Lock&Read, Write&Unlock are not supported"
14224 };
14225 static const true_false_string tfs_smb_flags_receive_buffer = {
14226         "Receive buffer has been posted",
14227         "Receive buffer has not been posted"
14228 };
14229 static const true_false_string tfs_smb_flags_caseless = {
14230         "Path names are caseless",
14231         "Path names are case sensitive"
14232 };
14233 static const true_false_string tfs_smb_flags_canon = {
14234         "Pathnames are canonicalized",
14235         "Pathnames are not canonicalized"
14236 };
14237 static const true_false_string tfs_smb_flags_oplock = {
14238         "OpLock requested/granted",
14239         "OpLock not requested/granted"
14240 };
14241 static const true_false_string tfs_smb_flags_notify = {
14242         "Notify client on all modifications",
14243         "Notify client only on open"
14244 };
14245 static const true_false_string tfs_smb_flags_response = {
14246         "Message is a response to the client/redirector",
14247         "Message is a request to the server"
14248 };
14249
14250 static int
14251 dissect_smb_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
14252 {
14253         guint8 mask;
14254         proto_item *item = NULL;
14255         proto_tree *tree = NULL;
14256
14257         mask = tvb_get_guint8(tvb, offset);
14258
14259         if(parent_tree){
14260                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
14261                         "Flags: 0x%02x", mask);
14262                 tree = proto_item_add_subtree(item, ett_smb_flags);
14263         }
14264         proto_tree_add_boolean(tree, hf_smb_flags_response,
14265                 tvb, offset, 1, mask);
14266         proto_tree_add_boolean(tree, hf_smb_flags_notify,
14267                 tvb, offset, 1, mask);
14268         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
14269                 tvb, offset, 1, mask);
14270         proto_tree_add_boolean(tree, hf_smb_flags_canon,
14271                 tvb, offset, 1, mask);
14272         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
14273                 tvb, offset, 1, mask);
14274         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
14275                 tvb, offset, 1, mask);
14276         proto_tree_add_boolean(tree, hf_smb_flags_lock,
14277                 tvb, offset, 1, mask);
14278         offset += 1;
14279         return offset;
14280 }
14281
14282
14283  
14284 static const true_false_string tfs_smb_flags2_long_names_allowed = {
14285         "Long file names are allowed in the response",
14286         "Long file names are not allowed in the response"
14287 };
14288 static const true_false_string tfs_smb_flags2_ea = {
14289         "Extended attributes are supported",
14290         "Extended attributes are not supported"
14291 };
14292 static const true_false_string tfs_smb_flags2_sec_sig = {
14293         "Security signatures are supported",
14294         "Security signatures are not supported"
14295 };
14296 static const true_false_string tfs_smb_flags2_long_names_used = {
14297         "Path names in request are long file names",
14298         "Path names in request are not long file names"
14299 };
14300 static const true_false_string tfs_smb_flags2_esn = {
14301         "Extended security negotiation is supported",
14302         "Extended security negotiation is not supported"
14303 };
14304 static const true_false_string tfs_smb_flags2_dfs = {
14305         "Resolve pathnames with Dfs",
14306         "Don't resolve pathnames with Dfs"
14307 };
14308 static const true_false_string tfs_smb_flags2_roe = {
14309         "Permit reads if execute-only",
14310         "Don't permit reads if execute-only"
14311 };
14312 static const true_false_string tfs_smb_flags2_nt_error = {
14313         "Error codes are NT error codes",
14314         "Error codes are DOS error codes"
14315 };
14316 static const true_false_string tfs_smb_flags2_string = {
14317         "Strings are Unicode",
14318         "Strings are ASCII"
14319 };
14320 static int
14321 dissect_smb_flags2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
14322 {
14323         guint16 mask;
14324         proto_item *item = NULL;
14325         proto_tree *tree = NULL;
14326
14327         mask = tvb_get_letohs(tvb, offset);
14328
14329         if(parent_tree){
14330                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
14331                         "Flags2: 0x%04x", mask);
14332                 tree = proto_item_add_subtree(item, ett_smb_flags2);
14333         }
14334
14335         proto_tree_add_boolean(tree, hf_smb_flags2_string,
14336                 tvb, offset, 2, mask);
14337         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
14338                 tvb, offset, 2, mask);
14339         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
14340                 tvb, offset, 2, mask);
14341         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
14342                 tvb, offset, 2, mask);
14343         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
14344                 tvb, offset, 2, mask);
14345         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
14346                 tvb, offset, 2, mask);
14347         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
14348                 tvb, offset, 2, mask);
14349         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
14350                 tvb, offset, 2, mask);
14351         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
14352                 tvb, offset, 2, mask);
14353
14354         offset += 2;
14355         return offset;
14356 }
14357
14358
14359
14360 #define SMB_FLAGS_DIRN 0x80
14361
14362
14363 static gboolean
14364 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
14365 {
14366         int offset = 0;
14367         proto_item *item = NULL, *hitem = NULL;
14368         proto_tree *tree = NULL, *htree = NULL;
14369         guint8          flags;
14370         guint16         flags2;
14371         smb_info_t      si;
14372         smb_saved_info_t *sip = NULL;
14373         smb_saved_info_key_t key;
14374         smb_saved_info_key_t *new_key;
14375         guint32 nt_status = 0;
14376         guint8 errclass = 0;
14377         guint16 errcode = 0;
14378         guint32 pid_mid;
14379         conversation_t *conversation;
14380
14381         top_tree=parent_tree;
14382
14383         /* must check that this really is a smb packet */
14384         if (!tvb_bytes_exist(tvb, 0, 4))
14385                 return FALSE;
14386
14387         if( (tvb_get_guint8(tvb, 0) != 0xff)
14388             || (tvb_get_guint8(tvb, 1) != 'S')
14389             || (tvb_get_guint8(tvb, 2) != 'M')
14390             || (tvb_get_guint8(tvb, 3) != 'B') ){
14391                 return FALSE;
14392         }
14393          
14394         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
14395                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
14396         }
14397         if (check_col(pinfo->cinfo, COL_INFO)){
14398                 col_clear(pinfo->cinfo, COL_INFO);
14399         }
14400
14401         /* start off using the local variable, we will allocate a new one if we
14402            need to*/
14403         si.cmd = tvb_get_guint8(tvb, offset+4);
14404         flags = tvb_get_guint8(tvb, offset+9);
14405         si.request = !(flags&SMB_FLAGS_DIRN);
14406         flags2 = tvb_get_letohs(tvb, offset+10);
14407         if(flags2 & 0x8000){
14408                 si.unicode = TRUE; /* Mark them as Unicode */
14409         } else {
14410                 si.unicode = FALSE;
14411         }
14412         si.tid = tvb_get_letohs(tvb, offset+24);
14413         si.pid = tvb_get_letohs(tvb, offset+26);
14414         si.uid = tvb_get_letohs(tvb, offset+28);
14415         si.mid = tvb_get_letohs(tvb, offset+30);
14416         pid_mid = (si.pid << 16) | si.mid;
14417         si.info_level = -1;
14418         si.info_count = -1;
14419
14420         if (parent_tree) {
14421                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset, 
14422                         -1, FALSE);
14423                 tree = proto_item_add_subtree(item, ett_smb);
14424
14425                 hitem = proto_tree_add_text(tree, tvb, offset, 32, 
14426                         "SMB Header");
14427
14428                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
14429         }
14430
14431         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
14432         offset += 4;  /* Skip the marker */
14433
14434         /* find which conversation we are part of and get the tables for that 
14435            conversation*/
14436         conversation = find_conversation(&pinfo->src, &pinfo->dst,
14437                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
14438         if(conversation){
14439                 si.ct=conversation_get_proto_data(conversation, proto_smb);
14440         } else {
14441                 /* OK this is a new conversation, we must create it
14442                    and attach appropriate data (matched and unmatched 
14443                    table for this conversation)
14444                 */
14445                 conversation = conversation_new(&pinfo->src, &pinfo->dst, 
14446                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
14447                 si.ct = g_mem_chunk_alloc(conv_tables_chunk);
14448                 conv_tables = g_slist_prepend(conv_tables, si.ct);
14449                 si.ct->matched= g_hash_table_new(smb_saved_info_hash_matched, 
14450                         smb_saved_info_equal_matched);
14451                 si.ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched, 
14452                         smb_saved_info_equal_unmatched);
14453                 si.ct->dcerpc_fid_to_frame=g_hash_table_new(
14454                         smb_saved_info_hash_unmatched, 
14455                         smb_saved_info_equal_unmatched);
14456                 si.ct->tid_service=g_hash_table_new(
14457                         smb_saved_info_hash_unmatched, 
14458                         smb_saved_info_equal_unmatched);
14459                 conversation_add_proto_data(conversation, proto_smb, si.ct);
14460         }
14461
14462         if( (si.request)
14463             &&  (si.mid==0)
14464             &&  (si.uid==0)
14465             &&  (si.pid==0)
14466             &&  (si.tid==0) ){
14467                 /* this is a broadcast SMB packet, there will not be a reply.
14468                    We dont need to do anything 
14469                 */
14470                 si.unidir = TRUE;
14471         } else if( (si.cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
14472                    ||(si.cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
14473                    ||(si.cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
14474                    ||(si.cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
14475                 /* Ok, we got a special request type. This request is either
14476                    an NT Cancel or a continuation relative to a real request
14477                    in an earlier packet.  In either case, we don't expect any
14478                    responses to this packet.  For continuations, any later
14479                    responses we see really just belong to the original request.
14480                    Anyway, we want to remember this packet somehow and
14481                    remember which original request it is associated with so
14482                    we can say nice things such as "This is a Cancellation to
14483                    the request in frame x", but we don't want the
14484                    request/response matching to get messed up.
14485
14486                    The only thing we do in this case is trying to find which original
14487                    request we match with and insert an entry for this "special" 
14488                    request for later reference. We continue to reference the original
14489                    requests smb_saved_info_t but we dont touch it or change anything
14490                    in it.
14491                 */
14492
14493                 si.unidir = TRUE;  /*we dont expect an answer to this one*/
14494
14495                 if(!pinfo->fd->flags.visited){
14496                         /* try to find which original call we match and if we 
14497                            find it add us to the matched table. Dont touch
14498                            anything else since we dont want this one to mess
14499                            up the request/response matching. We still consider
14500                            the initial call the real request and this is only
14501                            some sort of continuation.
14502                         */
14503                         /* we only check the unmatched table and assume that the
14504                            last seen MID matching ours is the right one.
14505                            This can fail but is better than nothing
14506                         */
14507                         sip=g_hash_table_lookup(si.ct->unmatched, (void *)pid_mid);
14508                         if(sip!=NULL){
14509                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14510                                 new_key->frame = pinfo->fd->num;
14511                                 new_key->pid_mid = pid_mid;
14512                                 g_hash_table_insert(si.ct->matched, new_key,
14513                                     sip);
14514                         }
14515                 } else {
14516                         /* we have seen this packet before; check the
14517                            matching table
14518                         */
14519                         key.frame = pinfo->fd->num;
14520                         key.pid_mid = pid_mid;
14521                         sip=g_hash_table_lookup(si.ct->matched, &key);
14522                         if(sip==NULL){
14523                         /*
14524                           We didn't find it.
14525                           Too bad, unfortunately there is not really much we can
14526                           do now since this means that we never saw the initial
14527                           request.
14528                          */
14529                         }
14530                 }
14531
14532
14533                 if(sip && sip->frame_req){
14534                         switch(si.cmd){
14535                         case SMB_COM_NT_CANCEL:
14536                                 proto_tree_add_uint(htree, hf_smb_cancel_to, 
14537                                                     tvb, 0, 0, sip->frame_req);
14538                                 break;
14539                         case SMB_COM_TRANSACTION_SECONDARY:
14540                         case SMB_COM_TRANSACTION2_SECONDARY:
14541                         case SMB_COM_NT_TRANSACT_SECONDARY:
14542                                 proto_tree_add_uint(htree, hf_smb_continuation_to, 
14543                                                     tvb, 0, 0, sip->frame_req);
14544                                 break;
14545                         }
14546                 } else {
14547                         switch(si.cmd){
14548                         case SMB_COM_NT_CANCEL:
14549                                 proto_tree_add_text(htree, tvb, 0, 0,
14550                                                     "Cancellation to: <unknown frame>");
14551                                 break;
14552                         case SMB_COM_TRANSACTION_SECONDARY:
14553                         case SMB_COM_TRANSACTION2_SECONDARY:
14554                         case SMB_COM_NT_TRANSACT_SECONDARY:
14555                                 proto_tree_add_text(htree, tvb, 0, 0,
14556                                                     "Continuation to: <unknown frame>");
14557                                 break;
14558                         }
14559                 }
14560         } else { /* normal bidirectional request or response */
14561                 si.unidir = FALSE;
14562
14563                 if(!pinfo->fd->flags.visited){
14564                         /* first see if we find an unmatched smb "equal" to 
14565                            the current one 
14566                         */
14567                         sip=g_hash_table_lookup(si.ct->unmatched, (void *)pid_mid);
14568                         if(sip!=NULL){
14569                                 gboolean cmd_match=FALSE;
14570
14571                                 /*
14572                                  * Make sure the SMB we found was the
14573                                  * same command, or a different command
14574                                  * that's another valid type of reply
14575                                  * to that command.
14576                                  */
14577                                 if(si.cmd==sip->cmd){
14578                                         cmd_match=TRUE;
14579                                 }
14580                                 else if(si.cmd==SMB_COM_NT_CANCEL){
14581                                         cmd_match=TRUE;
14582                                 }
14583                                 else if((si.cmd==SMB_COM_TRANSACTION_SECONDARY) 
14584                                      && (sip->cmd==SMB_COM_TRANSACTION)){
14585                                         cmd_match=TRUE;
14586                                 }
14587                                 else if((si.cmd==SMB_COM_TRANSACTION2_SECONDARY) 
14588                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
14589                                         cmd_match=TRUE;
14590                                 }
14591                                 else if((si.cmd==SMB_COM_NT_TRANSACT_SECONDARY) 
14592                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
14593                                         cmd_match=TRUE;
14594                                 }
14595
14596                                 if( (si.request) || (!cmd_match) ) {
14597                                         /* If we are processing an SMB request but there was already
14598                                            another "identical" smb resuest we had not matched yet.
14599                                            This must mean that either we have a retransmission or that the
14600                                            response to the previous one was lost and the client has reused
14601                                            the MID for this conversation. In either case it's not much more
14602                                            we can do than forget the old request and concentrate on the 
14603                                            present one instead.
14604
14605                                            We also do this cleanup if we see that the cmd in the original
14606                                            request in sip->cmd is not compatible with the current cmd.
14607                                            This is to prevent matching errors such as if there were two
14608                                            SMBs of different cmds but with identical MID and PID values and
14609                                            if ethereal lost the first reply and the second request.
14610                                         */
14611                                         g_hash_table_remove(si.ct->unmatched, (void *)pid_mid);
14612                                         sip=NULL; /* XXX should free it as well */
14613                                 } else {
14614                                         /* we have found a response to some request we have seen earlier.
14615                                            What we do now depends on whether this is the first response
14616                                            to that request we see (id frame_res==0) or not. 
14617                                         */
14618                                         if(sip->frame_res==0){
14619                                                 /* ok it is the first response we have seen to this packet */
14620                                                 sip->frame_res = pinfo->fd->num;
14621                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14622                                                 new_key->frame = sip->frame_req;
14623                                                 new_key->pid_mid = pid_mid;
14624                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
14625                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14626                                                 new_key->frame = sip->frame_res;
14627                                                 new_key->pid_mid = pid_mid;
14628                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
14629                                         } else {
14630                                                 /* we have already seen another response to this one, but
14631                                                    register it anyway so we see which request it matches 
14632                                                 */
14633                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14634                                                 new_key->frame = pinfo->fd->num;
14635                                                 new_key->pid_mid = pid_mid;
14636                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
14637                                         }
14638                                 }
14639                         }
14640                         if(si.request){
14641                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
14642                                 sip->frame_req = pinfo->fd->num;
14643                                 sip->frame_res = 0;
14644                                 sip->flags = 0;
14645                                 if(g_hash_table_lookup(si.ct->tid_service, (void *)si.tid)
14646                                     == (void *)TID_IPC) {
14647                                         sip->flags |= SMB_SIF_TID_IS_IPC;
14648                                 }
14649                                 sip->cmd = si.cmd;
14650                                 sip->extra_info = NULL;
14651                                 g_hash_table_insert(si.ct->unmatched, (void *)pid_mid, sip);
14652                         }
14653                 } else {
14654                         /* we have seen this packet before; check the
14655                            matching table.
14656                            If we haven't yet seen the reply, we won't
14657                            find the info for it; we don't need it, as
14658                            we only use it to save information, and, as
14659                            we've seen this packet before, we've already
14660                            saved the information.
14661                         */
14662                         key.frame = pinfo->fd->num;
14663                         key.pid_mid = pid_mid;
14664                         sip=g_hash_table_lookup(si.ct->matched, &key);
14665                 }
14666         }
14667
14668         /*
14669          * Pass the "sip" on to subdissectors through "si".
14670          */
14671         si.sip = sip;
14672
14673         if (sip != NULL) {
14674                 /*
14675                  * Put in fields for the frame number of the frame to which
14676                  * this is a response or the frame with the response to this
14677                  * frame - if we know the frame number (i.e., it's not 0).
14678                  */
14679                 if(si.request){
14680                         if (sip->frame_res != 0)
14681                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
14682                 } else {
14683                         if (sip->frame_req != 0)
14684                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
14685                 }
14686         }
14687
14688         /* smb command */
14689         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);
14690         offset += 1;
14691
14692         if(flags2 & 0x4000){
14693                 /* handle NT 32 bit error code */
14694
14695                 nt_status = tvb_get_letohl(tvb, offset);
14696
14697                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
14698                         TRUE);
14699                 offset += 4;
14700
14701         } else {
14702                 /* handle DOS error code & class */
14703                 errclass = tvb_get_guint8(tvb, offset);
14704                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
14705                         errclass);
14706                 offset += 1;
14707
14708                 /* reserved byte */
14709                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
14710                 offset += 1;
14711
14712                 /* error code */
14713                 /* XXX - the type of this field depends on the value of
14714                  * "errcls", so there is isn't a single value_string array
14715                  * fo it, so there can't be a single field for it.
14716                  */
14717                 errcode = tvb_get_letohs(tvb, offset);
14718                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
14719                         offset, 2, errcode, "Error Code: %s",
14720                         decode_smb_error(errclass, errcode));
14721                 offset += 2;
14722         }
14723
14724         /* flags */
14725         offset = dissect_smb_flags(tvb, pinfo, htree, offset);
14726
14727         /* flags2 */
14728         offset = dissect_smb_flags2(tvb, pinfo, htree, offset);
14729
14730         /*
14731          * The document at
14732          *
14733          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
14734          *
14735          * (a text version of "Microsoft Networks SMB FILE SHARING
14736          * PROTOCOL, Document Version 6.0p") says that:
14737          *
14738          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
14739          *      the "High Part of PID";
14740          *
14741          *      the next four bytes are reserved;
14742          *
14743          *      the next four bytes are, for SMB-over-IPX (with no
14744          *      NetBIOS involved) two bytes of Session ID and two bytes
14745          *      of SequenceNumber.
14746          *
14747          * If we ever implement SMB-over-IPX (which I suspect goes over
14748          * IPX sockets 0x0550, 0x0552, and maybe 0x0554, as per the
14749          * document in question), we'd probably want to have some way
14750          * to determine whether this is SMB-over-IPX or not (which could
14751          * be done by adding a PT_IPXSOCKET port type, having the
14752          * IPX dissector set "pinfo->srcport" and "pinfo->destport",
14753          * and having the SMB dissector check for a port type of
14754          * PT_IPXSOCKET and for "pinfo->match_port" being either
14755          * IPX_SOCKET_NWLINK_SMB_SERVER or IPX_SOCKET_NWLINK_SMB_REDIR
14756          * or, if it also uses 0x0554, IPX_SOCKET_NWLINK_SMB_MESSENGER).
14757          */
14758
14759         /* 12 reserved bytes */
14760         proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 12, TRUE);
14761         offset += 12;
14762
14763         /* TID */
14764         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si.tid);
14765         offset += 2;
14766
14767         /* PID */
14768         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si.pid);
14769         offset += 2;
14770
14771         /* UID */
14772         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si.uid);
14773         offset += 2;
14774
14775         /* MID */
14776         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si.mid);
14777         offset += 2;
14778
14779         pinfo->private_data = &si;
14780         dissect_smb_command(tvb, pinfo, parent_tree, offset, tree, si.cmd);
14781
14782         /* Append error info from this packet to info string. */
14783         if (!si.request && check_col(pinfo->cinfo, COL_INFO)) {
14784                 if (flags2 & 0x4000) {
14785                         /*
14786                          * The status is an NT status code; was there
14787                          * an error?
14788                          */
14789                         if (nt_status != 0) {
14790                                 /*
14791                                  * Yes.
14792                                  */
14793                                 col_append_fstr(
14794                                         pinfo->cinfo, COL_INFO, ", Error: %s",
14795                                         val_to_str(nt_status, NT_errors,
14796                                             "Unknown (0x%08X)"));
14797                         }
14798                 } else {
14799                         /*
14800                          * The status is a DOS error class and code; was
14801                          * there an error?
14802                          */
14803                         if (errclass != SMB_SUCCESS) {
14804                                 /*
14805                                  * Yes.
14806                                  */
14807                                 col_append_fstr(
14808                                         pinfo->cinfo, COL_INFO, ", Error: %s",
14809                                         decode_smb_error(errclass, errcode));
14810                         }
14811                 }
14812         }
14813
14814         return TRUE;
14815 }
14816
14817 void
14818 proto_register_smb(void)
14819 {
14820         static hf_register_info hf[] = {
14821         { &hf_smb_cmd,
14822                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
14823                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
14824
14825         { &hf_smb_word_count,
14826                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
14827                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
14828
14829         { &hf_smb_byte_count,
14830                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
14831                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
14832
14833         { &hf_smb_response_to,
14834                 { "Response to", "smb.response_to", FT_UINT32, BASE_DEC,
14835                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
14836
14837         { &hf_smb_response_in,
14838                 { "Response in", "smb.response_in", FT_UINT32, BASE_DEC,
14839                 NULL, 0, "The response to this packet is in this packet", HFILL }},
14840
14841         { &hf_smb_continuation_to,
14842                 { "Continuation to", "smb.continuation_to", FT_UINT32, BASE_DEC,
14843                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
14844
14845         { &hf_smb_nt_status,
14846                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
14847                 VALS(NT_errors), 0, "NT Status code", HFILL }},
14848
14849         { &hf_smb_error_class,
14850                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
14851                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
14852
14853         { &hf_smb_error_code,
14854                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
14855                 NULL, 0, "DOS Error Code", HFILL }},
14856
14857         { &hf_smb_reserved,
14858                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
14859                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
14860
14861         { &hf_smb_pid,
14862                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
14863                 NULL, 0, "Process ID", HFILL }},
14864
14865         { &hf_smb_tid,
14866                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
14867                 NULL, 0, "Tree ID", HFILL }},
14868
14869         { &hf_smb_uid,
14870                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
14871                 NULL, 0, "User ID", HFILL }},
14872
14873         { &hf_smb_mid,
14874                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
14875                 NULL, 0, "Multiplex ID", HFILL }},
14876
14877         { &hf_smb_flags_lock,
14878                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
14879                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
14880
14881         { &hf_smb_flags_receive_buffer,
14882                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
14883                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
14884
14885         { &hf_smb_flags_caseless,
14886                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
14887                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
14888
14889         { &hf_smb_flags_canon,
14890                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
14891                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
14892
14893         { &hf_smb_flags_oplock,
14894                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
14895                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
14896
14897         { &hf_smb_flags_notify,
14898                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
14899                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
14900
14901         { &hf_smb_flags_response,
14902                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
14903                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
14904
14905         { &hf_smb_flags2_long_names_allowed,
14906                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
14907                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
14908
14909         { &hf_smb_flags2_ea,
14910                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
14911                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
14912
14913         { &hf_smb_flags2_sec_sig,
14914                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
14915                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
14916
14917         { &hf_smb_flags2_long_names_used,
14918                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
14919                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
14920
14921         { &hf_smb_flags2_esn,
14922                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
14923                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
14924
14925         { &hf_smb_flags2_dfs,
14926                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
14927                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
14928
14929         { &hf_smb_flags2_roe,
14930                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
14931                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
14932
14933         { &hf_smb_flags2_nt_error,
14934                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
14935                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
14936
14937         { &hf_smb_flags2_string,
14938                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
14939                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
14940
14941         { &hf_smb_buffer_format,
14942                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
14943                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
14944
14945         { &hf_smb_dialect_name,
14946                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
14947                 NULL, 0, "Name of dialect", HFILL }},
14948
14949         { &hf_smb_dialect_index,
14950                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
14951                 NULL, 0, "Index of selected dialect", HFILL }},
14952
14953         { &hf_smb_max_trans_buf_size,
14954                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
14955                 NULL, 0, "Maximum transmit buffer size", HFILL }},
14956
14957         { &hf_smb_max_mpx_count,
14958                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
14959                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
14960
14961         { &hf_smb_max_vcs_num,
14962                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
14963                 NULL, 0, "Maximum VCs between client and server", HFILL }},
14964
14965         { &hf_smb_session_key,
14966                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
14967                 NULL, 0, "Unique token identifying this session", HFILL }},
14968
14969         { &hf_smb_server_timezone,
14970                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
14971                 NULL, 0, "Current timezone at server.", HFILL }},
14972
14973         { &hf_smb_encryption_key_length,
14974                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
14975                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
14976
14977         { &hf_smb_encryption_key,
14978                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
14979                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
14980
14981         { &hf_smb_primary_domain,
14982                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
14983                 NULL, 0, "The server's primary domain", HFILL }},
14984
14985         { &hf_smb_max_raw_buf_size,
14986                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
14987                 NULL, 0, "Maximum raw buffer size", HFILL }},
14988
14989         { &hf_smb_server_guid,
14990                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
14991                 NULL, 0, "Globally unique identifier for this server", HFILL }},
14992
14993         { &hf_smb_security_blob_len,
14994                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
14995                 NULL, 0, "Security blob length", HFILL }},
14996
14997         { &hf_smb_security_blob,
14998                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
14999                 NULL, 0, "Security blob", HFILL }},
15000
15001         { &hf_smb_sm_mode16,
15002                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
15003                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
15004
15005         { &hf_smb_sm_password16,
15006                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
15007                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
15008
15009         { &hf_smb_sm_mode,
15010                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
15011                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
15012
15013         { &hf_smb_sm_password,
15014                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
15015                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
15016
15017         { &hf_smb_sm_signatures,
15018                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
15019                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
15020
15021         { &hf_smb_sm_sig_required,
15022                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
15023                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
15024
15025         { &hf_smb_rm_read,
15026                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
15027                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
15028
15029         { &hf_smb_rm_write,
15030                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
15031                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
15032
15033         { &hf_smb_server_date_time,
15034                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
15035                 NULL, 0, "Current date and time at server", HFILL }},
15036
15037         { &hf_smb_server_smb_date,
15038                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
15039                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
15040
15041         { &hf_smb_server_smb_time,
15042                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
15043                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
15044
15045         { &hf_smb_server_cap_raw_mode,
15046                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
15047                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
15048
15049         { &hf_smb_server_cap_mpx_mode,
15050                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
15051                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
15052
15053         { &hf_smb_server_cap_unicode,
15054                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
15055                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
15056
15057         { &hf_smb_server_cap_large_files,
15058                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
15059                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
15060
15061         { &hf_smb_server_cap_nt_smbs,
15062                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
15063                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
15064
15065         { &hf_smb_server_cap_rpc_remote_apis,
15066                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
15067                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
15068
15069         { &hf_smb_server_cap_nt_status,
15070                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
15071                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
15072
15073         { &hf_smb_server_cap_level_ii_oplocks,
15074                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
15075                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
15076
15077         { &hf_smb_server_cap_lock_and_read,
15078                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
15079                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
15080
15081         { &hf_smb_server_cap_nt_find,
15082                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
15083                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
15084
15085         { &hf_smb_server_cap_dfs,
15086                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
15087                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
15088
15089         { &hf_smb_server_cap_infolevel_passthru,
15090                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
15091                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
15092
15093         { &hf_smb_server_cap_large_readx,
15094                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
15095                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
15096
15097         { &hf_smb_server_cap_large_writex,
15098                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
15099                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
15100
15101         { &hf_smb_server_cap_unix,
15102                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
15103                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
15104
15105         { &hf_smb_server_cap_reserved,
15106                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
15107                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
15108
15109         { &hf_smb_server_cap_bulk_transfer,
15110                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
15111                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
15112
15113         { &hf_smb_server_cap_compressed_data,
15114                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
15115                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
15116
15117         { &hf_smb_server_cap_extended_security,
15118                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
15119                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
15120
15121         { &hf_smb_system_time,
15122                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
15123                 NULL, 0, "System Time", HFILL }},
15124
15125         { &hf_smb_unknown,
15126                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
15127                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
15128
15129         { &hf_smb_dir_name,
15130                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
15131                 NULL, 0, "SMB Directory Name", HFILL }},
15132
15133         { &hf_smb_echo_count,
15134                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
15135                 NULL, 0, "Number of times to echo data back", HFILL }},
15136
15137         { &hf_smb_echo_data,
15138                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
15139                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
15140
15141         { &hf_smb_echo_seq_num,
15142                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
15143                 NULL, 0, "Sequence number for this echo response", HFILL }},
15144
15145         { &hf_smb_max_buf_size,
15146                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
15147                 NULL, 0, "Max client buffer size", HFILL }},
15148
15149         { &hf_smb_path,
15150                 { "Path", "smb.path", FT_STRING, BASE_NONE,
15151                 NULL, 0, "Path. Server name and share name", HFILL }},
15152
15153         { &hf_smb_service,
15154                 { "Service", "smb.service", FT_STRING, BASE_NONE,
15155                 NULL, 0, "Service name", HFILL }},
15156
15157         { &hf_smb_password,
15158                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
15159                 NULL, 0, "Password", HFILL }},
15160
15161         { &hf_smb_ansi_password,
15162                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
15163                 NULL, 0, "ANSI Password", HFILL }},
15164
15165         { &hf_smb_unicode_password,
15166                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
15167                 NULL, 0, "Unicode Password", HFILL }},
15168
15169         { &hf_smb_move_flags_file,
15170                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
15171                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
15172
15173         { &hf_smb_move_flags_dir,
15174                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
15175                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
15176
15177         { &hf_smb_move_flags_verify,
15178                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
15179                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
15180
15181         { &hf_smb_move_files_moved,
15182                 { "Files Moved", "smb.move.files_moved", FT_UINT16, BASE_DEC,
15183                 NULL, 0, "Number of files moved", HFILL }},
15184
15185         { &hf_smb_count,
15186                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
15187                 NULL, 0, "Count number of items/bytes", HFILL }},
15188
15189         { &hf_smb_file_name,
15190                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
15191                 NULL, 0, "File Name", HFILL }},
15192
15193         { &hf_smb_open_function_create,
15194                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
15195                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
15196
15197         { &hf_smb_open_function_open,
15198                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
15199                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
15200
15201         { &hf_smb_fid,
15202                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
15203                 NULL, 0, "FID: File ID", HFILL }},
15204
15205         { &hf_smb_file_attr_read_only_16bit,
15206                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
15207                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
15208
15209         { &hf_smb_file_attr_read_only_8bit,
15210                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
15211                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
15212
15213         { &hf_smb_file_attr_hidden_16bit,
15214                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
15215                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
15216
15217         { &hf_smb_file_attr_hidden_8bit,
15218                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
15219                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
15220
15221         { &hf_smb_file_attr_system_16bit,
15222                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
15223                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
15224
15225         { &hf_smb_file_attr_system_8bit,
15226                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
15227                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
15228
15229         { &hf_smb_file_attr_volume_16bit,
15230                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
15231                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
15232
15233         { &hf_smb_file_attr_volume_8bit,
15234                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
15235                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
15236
15237         { &hf_smb_file_attr_directory_16bit,
15238                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
15239                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
15240
15241         { &hf_smb_file_attr_directory_8bit,
15242                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
15243                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
15244
15245         { &hf_smb_file_attr_archive_16bit,
15246                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
15247                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
15248
15249         { &hf_smb_file_attr_archive_8bit,
15250                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
15251                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
15252
15253         { &hf_smb_file_attr_device,
15254                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
15255                 TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
15256
15257         { &hf_smb_file_attr_normal,
15258                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
15259                 TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
15260
15261         { &hf_smb_file_attr_temporary,
15262                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
15263                 TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
15264
15265         { &hf_smb_file_attr_sparse,
15266                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
15267                 TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
15268
15269         { &hf_smb_file_attr_reparse,
15270                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
15271                 TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
15272
15273         { &hf_smb_file_attr_compressed,
15274                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
15275                 TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
15276
15277         { &hf_smb_file_attr_offline,
15278                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
15279                 TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
15280
15281         { &hf_smb_file_attr_not_content_indexed,
15282                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
15283                 TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
15284
15285         { &hf_smb_file_attr_encrypted,
15286                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
15287                 TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
15288
15289         { &hf_smb_file_size,
15290                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
15291                 NULL, 0, "File Size", HFILL }},
15292
15293         { &hf_smb_search_attribute_read_only,
15294                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
15295                 TFS(&tfs_search_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
15296
15297         { &hf_smb_search_attribute_hidden,
15298                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
15299                 TFS(&tfs_search_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
15300
15301         { &hf_smb_search_attribute_system,
15302                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
15303                 TFS(&tfs_search_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
15304
15305         { &hf_smb_search_attribute_volume,
15306                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
15307                 TFS(&tfs_search_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
15308
15309         { &hf_smb_search_attribute_directory,
15310                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
15311                 TFS(&tfs_search_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
15312
15313         { &hf_smb_search_attribute_archive,
15314                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
15315                 TFS(&tfs_search_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
15316
15317         { &hf_smb_access_mode,
15318                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
15319                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
15320
15321         { &hf_smb_access_sharing,
15322                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
15323                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
15324
15325         { &hf_smb_access_locality,
15326                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
15327                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
15328
15329         { &hf_smb_access_caching,
15330                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
15331                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
15332
15333         { &hf_smb_access_writetru,
15334                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
15335                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
15336
15337         { &hf_smb_create_time,
15338                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
15339                 NULL, 0, "Creation Time", HFILL }},
15340
15341         { &hf_smb_create_dos_date,
15342                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
15343                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
15344
15345         { &hf_smb_create_dos_time,
15346                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
15347                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
15348
15349         { &hf_smb_last_write_time,
15350                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
15351                 NULL, 0, "Time this file was last written to", HFILL }},
15352
15353         { &hf_smb_last_write_dos_date,
15354                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
15355                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
15356
15357         { &hf_smb_last_write_dos_time,
15358                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
15359                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
15360
15361         { &hf_smb_old_file_name,
15362                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
15363                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
15364
15365         { &hf_smb_offset,
15366                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
15367                 NULL, 0, "Offset in file", HFILL }},
15368
15369         { &hf_smb_remaining,
15370                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
15371                 NULL, 0, "Remaining number of bytes", HFILL }},
15372
15373         { &hf_smb_padding,
15374                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
15375                 NULL, 0, "Padding or unknown data", HFILL }},
15376
15377         { &hf_smb_file_data,
15378                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
15379                 NULL, 0, "Data read/written to the file", HFILL }},
15380
15381         { &hf_smb_total_data_len,
15382                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
15383                 NULL, 0, "Total length of data", HFILL }},
15384
15385         { &hf_smb_data_len,
15386                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
15387                 NULL, 0, "Length of data", HFILL }},
15388
15389         { &hf_smb_seek_mode,
15390                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
15391                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
15392
15393         { &hf_smb_access_time,
15394                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
15395                 NULL, 0, "Last Access Time", HFILL }},
15396
15397         { &hf_smb_access_dos_date,
15398                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
15399                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
15400
15401         { &hf_smb_access_dos_time,
15402                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
15403                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
15404
15405         { &hf_smb_data_size,
15406                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
15407                 NULL, 0, "Data Size", HFILL }},
15408
15409         { &hf_smb_alloc_size,
15410                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
15411                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
15412
15413         { &hf_smb_max_count,
15414                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
15415                 NULL, 0, "Maximum Count", HFILL }},
15416
15417         { &hf_smb_min_count,
15418                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
15419                 NULL, 0, "Minimum Count", HFILL }},
15420
15421         { &hf_smb_timeout,
15422                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
15423                 NULL, 0, "Timeout in miliseconds", HFILL }},
15424
15425         { &hf_smb_high_offset,
15426                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
15427                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
15428
15429         { &hf_smb_units,
15430                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
15431                 NULL, 0, "Total number of units at server", HFILL }},
15432
15433         { &hf_smb_bpu,
15434                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
15435                 NULL, 0, "Blocks per unit at server", HFILL }},
15436
15437         { &hf_smb_blocksize,
15438                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
15439                 NULL, 0, "Block size (in bytes) at server", HFILL }},
15440
15441         { &hf_smb_freeunits,
15442                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
15443                 NULL, 0, "Number of free units at server", HFILL }},
15444
15445         { &hf_smb_data_offset,
15446                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
15447                 NULL, 0, "Data Offset", HFILL }},
15448
15449         { &hf_smb_dcm,
15450                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
15451                 NULL, 0, "Data Compaction Mode", HFILL }},
15452
15453         { &hf_smb_request_mask,
15454                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
15455                 NULL, 0, "Connectionless mode mask", HFILL }},
15456
15457         { &hf_smb_response_mask,
15458                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
15459                 NULL, 0, "Connectionless mode mask", HFILL }},
15460
15461         { &hf_smb_sid,
15462                 { "SID", "smb.sid", FT_UINT16, BASE_HEX,
15463                 NULL, 0, "SID: Search ID, handle for find operations", HFILL }},
15464
15465         { &hf_smb_write_mode_write_through,
15466                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
15467                 TFS(&tfs_write_mode_write_through), 0x0001, "Write through mode requested?", HFILL }},
15468
15469         { &hf_smb_write_mode_return_remaining,
15470                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
15471                 TFS(&tfs_write_mode_return_remaining), 0x0002, "Return remaining data responses?", HFILL }},
15472
15473         { &hf_smb_write_mode_raw,
15474                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
15475                 TFS(&tfs_write_mode_raw), 0x0004, "Use WriteRawNamedPipe?", HFILL }},
15476
15477         { &hf_smb_write_mode_message_start,
15478                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
15479                 TFS(&tfs_write_mode_message_start), 0x0008, "Is this the start of a message?", HFILL }},
15480
15481         { &hf_smb_write_mode_connectionless,
15482                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
15483                 TFS(&tfs_write_mode_connectionless), 0x0080, "Connectionless mode requested?", HFILL }},
15484
15485         { &hf_smb_resume_key_len,
15486                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
15487                 NULL, 0, "Resume Key length", HFILL }},
15488
15489         { &hf_smb_resume_server_cookie,
15490                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
15491                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
15492
15493         { &hf_smb_resume_client_cookie,
15494                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
15495                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
15496
15497         { &hf_smb_andxoffset,
15498                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
15499                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
15500
15501         { &hf_smb_lock_type_large,
15502                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
15503                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
15504
15505         { &hf_smb_lock_type_cancel,
15506                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
15507                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
15508
15509         { &hf_smb_lock_type_change,
15510                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
15511                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
15512
15513         { &hf_smb_lock_type_oplock,
15514                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
15515                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
15516
15517         { &hf_smb_lock_type_shared,
15518                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
15519                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
15520
15521         { &hf_smb_locking_ol,
15522                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
15523                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
15524
15525         { &hf_smb_number_of_locks,
15526                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
15527                 NULL, 0, "Number of lock requests in this request", HFILL }},
15528
15529         { &hf_smb_number_of_unlocks,
15530                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
15531                 NULL, 0, "Number of unlock requests in this request", HFILL }},
15532
15533         { &hf_smb_lock_long_length,
15534                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
15535                 NULL, 0, "Length of lock/unlock region", HFILL }},
15536
15537         { &hf_smb_lock_long_offset,
15538                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
15539                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
15540
15541         { &hf_smb_file_type,
15542                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
15543                 VALS(filetype_vals), 0, "Type of file", HFILL }},
15544
15545         { &hf_smb_ipc_state_nonblocking,
15546                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
15547                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
15548
15549         { &hf_smb_ipc_state_endpoint,
15550                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
15551                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
15552
15553         { &hf_smb_ipc_state_pipe_type,
15554                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
15555                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
15556
15557         { &hf_smb_ipc_state_read_mode,
15558                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
15559                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
15560
15561         { &hf_smb_ipc_state_icount,
15562                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
15563                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
15564
15565         { &hf_smb_server_fid,
15566                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
15567                 NULL, 0, "Server unique File ID", HFILL }},
15568
15569         { &hf_smb_open_flags_add_info,
15570                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
15571                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
15572
15573         { &hf_smb_open_flags_ex_oplock,
15574                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
15575                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
15576
15577         { &hf_smb_open_flags_batch_oplock,
15578                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
15579                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
15580
15581         { &hf_smb_open_flags_ealen,
15582                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
15583                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
15584
15585         { &hf_smb_open_action_open,
15586                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
15587                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
15588
15589         { &hf_smb_open_action_lock,
15590                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
15591                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
15592
15593         { &hf_smb_vc_num,
15594                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
15595                 NULL, 0, "VC Number", HFILL }},
15596
15597         { &hf_smb_password_len,
15598                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
15599                 NULL, 0, "Length of password", HFILL }},
15600
15601         { &hf_smb_ansi_password_len,
15602                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
15603                 NULL, 0, "Length of ANSI password", HFILL }},
15604
15605         { &hf_smb_unicode_password_len,
15606                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
15607                 NULL, 0, "Length of Unicode password", HFILL }},
15608
15609         { &hf_smb_account,
15610                 { "Account", "smb.account", FT_STRING, BASE_NONE,
15611                 NULL, 0, "Account, username", HFILL }},
15612
15613         { &hf_smb_os,
15614                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
15615                 NULL, 0, "Which OS we are running", HFILL }},
15616
15617         { &hf_smb_lanman,
15618                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
15619                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
15620
15621         { &hf_smb_setup_action_guest,
15622                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
15623                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
15624
15625         { &hf_smb_fs,
15626                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
15627                 NULL, 0, "Native File System", HFILL }},
15628
15629         { &hf_smb_connect_flags_dtid,
15630                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
15631                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
15632
15633         { &hf_smb_connect_support_search,
15634                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
15635                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
15636
15637         { &hf_smb_connect_support_in_dfs,
15638                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
15639                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
15640
15641         { &hf_smb_max_setup_count,
15642                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
15643                 NULL, 0, "Maximum number of setup words to return", HFILL }},
15644
15645         { &hf_smb_total_param_count,
15646                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
15647                 NULL, 0, "Total number of parameter bytes", HFILL }},
15648
15649         { &hf_smb_total_data_count,
15650                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
15651                 NULL, 0, "Total number of data bytes", HFILL }},
15652
15653         { &hf_smb_max_param_count,
15654                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
15655                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
15656
15657         { &hf_smb_max_data_count,
15658                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
15659                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
15660
15661         { &hf_smb_param_disp16,
15662                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
15663                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
15664
15665         { &hf_smb_param_count16,
15666                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
15667                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
15668
15669         { &hf_smb_param_offset16,
15670                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
15671                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
15672
15673         { &hf_smb_param_disp32,
15674                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
15675                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
15676
15677         { &hf_smb_param_count32,
15678                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
15679                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
15680
15681         { &hf_smb_param_offset32,
15682                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
15683                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
15684
15685         { &hf_smb_data_count16,
15686                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
15687                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
15688
15689         { &hf_smb_data_disp16,
15690                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
15691                 NULL, 0, "Data Displacement", HFILL }},
15692
15693         { &hf_smb_data_offset16,
15694                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
15695                 NULL, 0, "Data Offset", HFILL }},
15696
15697         { &hf_smb_data_count32,
15698                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
15699                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
15700
15701         { &hf_smb_data_disp32,
15702                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
15703                 NULL, 0, "Data Displacement", HFILL }},
15704
15705         { &hf_smb_data_offset32,
15706                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
15707                 NULL, 0, "Data Offset", HFILL }},
15708
15709         { &hf_smb_setup_count,
15710                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
15711                 NULL, 0, "Number of setup words in this buffer", HFILL }},
15712
15713         { &hf_smb_nt_trans_subcmd,
15714                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
15715                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
15716
15717         { &hf_smb_nt_ioctl_function_code,
15718                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
15719                 NULL, 0, "NT IOCTL function code", HFILL }},
15720
15721         { &hf_smb_nt_ioctl_isfsctl,
15722                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
15723                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
15724
15725         { &hf_smb_nt_ioctl_flags_root_handle,
15726                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
15727                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
15728
15729         { &hf_smb_nt_ioctl_data,
15730                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
15731                 NULL, 0, "Data for the IOCTL call", HFILL }},
15732
15733         { &hf_smb_nt_notify_action,
15734                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
15735                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
15736
15737         { &hf_smb_nt_notify_watch_tree,
15738                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
15739                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
15740
15741         { &hf_smb_nt_notify_stream_write,
15742                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
15743                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
15744
15745         { &hf_smb_nt_notify_stream_size,
15746                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
15747                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
15748
15749         { &hf_smb_nt_notify_stream_name,
15750                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
15751                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
15752
15753         { &hf_smb_nt_notify_security,
15754                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
15755                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
15756
15757         { &hf_smb_nt_notify_ea,
15758                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
15759                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
15760
15761         { &hf_smb_nt_notify_creation,
15762                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
15763                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
15764
15765         { &hf_smb_nt_notify_last_access,
15766                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
15767                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
15768
15769         { &hf_smb_nt_notify_last_write,
15770                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
15771                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
15772
15773         { &hf_smb_nt_notify_size,
15774                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
15775                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
15776
15777         { &hf_smb_nt_notify_attributes,
15778                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
15779                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
15780
15781         { &hf_smb_nt_notify_dir_name,
15782                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
15783                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
15784
15785         { &hf_smb_nt_notify_file_name,
15786                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
15787                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
15788
15789         { &hf_smb_root_dir_fid,
15790                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
15791                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
15792
15793         { &hf_smb_alloc_size64,
15794                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
15795                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
15796
15797         { &hf_smb_nt_create_disposition,
15798                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
15799                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
15800
15801         { &hf_smb_sd_length,
15802                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
15803                 NULL, 0, "Total length of security descriptor", HFILL }},
15804
15805         { &hf_smb_ea_length,
15806                 { "EA Length", "smb.ea.length", FT_UINT32, BASE_DEC,
15807                 NULL, 0, "Total EA length for opened file", HFILL }},
15808
15809         { &hf_smb_file_name_len,
15810                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
15811                 NULL, 0, "Length of File Name", HFILL }},
15812
15813         { &hf_smb_nt_impersonation_level,
15814                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
15815                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
15816
15817         { &hf_smb_nt_security_flags_context_tracking,
15818                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
15819                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
15820
15821         { &hf_smb_nt_security_flags_effective_only,
15822                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
15823                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
15824
15825         { &hf_smb_nt_access_mask_generic_read,
15826                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
15827                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
15828
15829         { &hf_smb_nt_access_mask_generic_write,
15830                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
15831                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
15832
15833         { &hf_smb_nt_access_mask_generic_execute,
15834                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
15835                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
15836
15837         { &hf_smb_nt_access_mask_generic_all,
15838                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
15839                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
15840
15841         { &hf_smb_nt_access_mask_maximum_allowed,
15842                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
15843                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
15844
15845         { &hf_smb_nt_access_mask_system_security,
15846                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
15847                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
15848
15849         { &hf_smb_nt_access_mask_synchronize,
15850                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
15851                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
15852
15853         { &hf_smb_nt_access_mask_write_owner,
15854                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
15855                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
15856
15857         { &hf_smb_nt_access_mask_write_dac,
15858                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
15859                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
15860
15861         { &hf_smb_nt_access_mask_read_control,
15862                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
15863                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
15864
15865         { &hf_smb_nt_access_mask_delete,
15866                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
15867                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
15868
15869         { &hf_smb_nt_access_mask_write_attributes,
15870                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
15871                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
15872
15873         { &hf_smb_nt_access_mask_read_attributes,
15874                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
15875                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
15876
15877         { &hf_smb_nt_access_mask_delete_child,
15878                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
15879                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
15880
15881         /*
15882          * "Execute" for files, "traverse" for directories.
15883          */
15884         { &hf_smb_nt_access_mask_execute,
15885                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
15886                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
15887
15888         { &hf_smb_nt_access_mask_write_ea,
15889                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
15890                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
15891
15892         { &hf_smb_nt_access_mask_read_ea,
15893                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
15894                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
15895
15896         /*
15897          * "Append data" for files, "add subdirectory" for directories,
15898          * "create pipe instance" for named pipes.
15899          */
15900         { &hf_smb_nt_access_mask_append,
15901                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
15902                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
15903
15904         /*
15905          * "Write data" for files and pipes, "add file" for directory.
15906          */
15907         { &hf_smb_nt_access_mask_write,
15908                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
15909                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
15910
15911         /*
15912          * "Read data" for files and pipes, "list directory" for directory.
15913          */
15914         { &hf_smb_nt_access_mask_read,
15915                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
15916                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
15917
15918         { &hf_smb_nt_create_bits_oplock,
15919                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
15920                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
15921
15922         { &hf_smb_nt_create_bits_boplock,
15923                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
15924                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
15925
15926         { &hf_smb_nt_create_bits_dir,
15927                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
15928                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
15929
15930         { &hf_smb_nt_create_options_directory_file,
15931                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
15932                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
15933
15934         { &hf_smb_nt_create_options_write_through,
15935                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
15936                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
15937
15938         { &hf_smb_nt_create_options_sequential_only,
15939                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
15940                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
15941
15942         { &hf_smb_nt_create_options_sync_io_alert,
15943                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
15944                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
15945
15946         { &hf_smb_nt_create_options_sync_io_nonalert,
15947                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
15948                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
15949
15950         { &hf_smb_nt_create_options_non_directory_file,
15951                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
15952                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
15953
15954         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
15955            and "NtOpenFile()"; is that sent over the wire?  Network
15956            Monitor thinks so, but its author may just have grabbed
15957            the flag bits from a system header file. */
15958
15959         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
15960            and "NtOpenFile()"; is that sent over the wire?  NetMon
15961            thinks so, but see previous comment. */
15962
15963         { &hf_smb_nt_create_options_no_ea_knowledge,
15964                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
15965                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
15966
15967         { &hf_smb_nt_create_options_eight_dot_three_only,
15968                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
15969                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
15970
15971         { &hf_smb_nt_create_options_random_access,
15972                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
15973                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
15974
15975         { &hf_smb_nt_create_options_delete_on_close,
15976                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
15977                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
15978
15979         /* 0x00002000 is "open by FID", or something such as that (which
15980            I suspect is like "open by inumber" on UNIX), at least in
15981            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
15982            wire?  NetMon thinks so, but see previous comment. */
15983
15984         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
15985            and "NtOpenFile()"; is that sent over the wire?  NetMon
15986            thinks so, but see previous comment. */
15987
15988         { &hf_smb_nt_share_access_read,
15989                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
15990                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
15991
15992         { &hf_smb_nt_share_access_write,
15993                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
15994                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
15995
15996         { &hf_smb_nt_share_access_delete,
15997                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
15998                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
15999
16000         { &hf_smb_file_eattr_read_only,
16001                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
16002                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
16003
16004         { &hf_smb_file_eattr_hidden,
16005                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
16006                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
16007
16008         { &hf_smb_file_eattr_system,
16009                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
16010                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
16011
16012         { &hf_smb_file_eattr_volume,
16013                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
16014                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
16015
16016         { &hf_smb_file_eattr_directory,
16017                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
16018                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
16019
16020         { &hf_smb_file_eattr_archive,
16021                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
16022                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
16023
16024         { &hf_smb_file_eattr_device,
16025                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
16026                 TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
16027
16028         { &hf_smb_file_eattr_normal,
16029                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
16030                 TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
16031
16032         { &hf_smb_file_eattr_temporary,
16033                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
16034                 TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
16035
16036         { &hf_smb_file_eattr_sparse,
16037                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
16038                 TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
16039
16040         { &hf_smb_file_eattr_reparse,
16041                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
16042                 TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
16043
16044         { &hf_smb_file_eattr_compressed,
16045                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
16046                 TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
16047
16048         { &hf_smb_file_eattr_offline,
16049                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
16050                 TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
16051
16052         { &hf_smb_file_eattr_not_content_indexed,
16053                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
16054                 TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
16055
16056         { &hf_smb_file_eattr_encrypted,
16057                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
16058                 TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
16059
16060         { &hf_smb_file_eattr_write_through,
16061                 { "Write Through", "smb.file_attribute.write_through", FT_BOOLEAN, 32,
16062                 TFS(&tfs_file_attribute_write_through), FILE_ATTRIBUTE_WRITE_THROUGH, "Does this object need write through?", HFILL }},
16063
16064         { &hf_smb_file_eattr_no_buffering,
16065                 { "No Buffering", "smb.file_attribute.no_buffering", FT_BOOLEAN, 32,
16066                 TFS(&tfs_file_attribute_no_buffering), FILE_ATTRIBUTE_NO_BUFFERING, "May the server buffer this object?", HFILL }},
16067
16068         { &hf_smb_file_eattr_random_access,
16069                 { "Random Access", "smb.file_attribute.random_access", FT_BOOLEAN, 32,
16070                 TFS(&tfs_file_attribute_random_access), FILE_ATTRIBUTE_RANDOM_ACCESS, "Optimize for random access", HFILL }},
16071
16072         { &hf_smb_file_eattr_sequential_scan,
16073                 { "Sequential Scan", "smb.file_attribute.sequential_scan", FT_BOOLEAN, 32,
16074                 TFS(&tfs_file_attribute_sequential_scan), FILE_ATTRIBUTE_SEQUENTIAL_SCAN, "Optimize for sequential scan", HFILL }},
16075
16076         { &hf_smb_file_eattr_delete_on_close,
16077                 { "Delete on Close", "smb.file_attribute.delete_on_close", FT_BOOLEAN, 32,
16078                 TFS(&tfs_file_attribute_delete_on_close), FILE_ATTRIBUTE_DELETE_ON_CLOSE, "Should this object be deleted on close?", HFILL }},
16079
16080         { &hf_smb_file_eattr_backup_semantics,
16081                 { "Backup", "smb.file_attribute.backup_semantics", FT_BOOLEAN, 32,
16082                 TFS(&tfs_file_attribute_backup_semantics), FILE_ATTRIBUTE_BACKUP_SEMANTICS, "Does this object need/support backup semantics", HFILL }},
16083
16084         { &hf_smb_file_eattr_posix_semantics,
16085                 { "Posix", "smb.file_attribute.posix_semantics", FT_BOOLEAN, 32,
16086                 TFS(&tfs_file_attribute_posix_semantics), FILE_ATTRIBUTE_POSIX_SEMANTICS, "Does this object need/support POSIX semantics?", HFILL }},
16087
16088         { &hf_smb_sec_desc_len,
16089                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
16090                 NULL, 0, "Security Descriptor Length", HFILL }},
16091
16092         { &hf_smb_nt_qsd_owner,
16093                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
16094                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
16095
16096         { &hf_smb_nt_qsd_group,
16097                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
16098                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
16099
16100         { &hf_smb_nt_qsd_dacl,
16101                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
16102                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
16103
16104         { &hf_smb_nt_qsd_sacl,
16105                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
16106                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
16107
16108         { &hf_smb_extended_attributes,
16109                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
16110                 NULL, 0, "Extended Attributes", HFILL }},
16111
16112         { &hf_smb_oplock_level,
16113                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
16114                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
16115
16116         { &hf_smb_create_action,
16117                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
16118                 VALS(create_disposition_vals), 0, "Type of action taken", HFILL }},
16119
16120         { &hf_smb_ea_error_offset,
16121                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
16122                 NULL, 0, "Offset into EA list if EA error", HFILL }},
16123
16124         { &hf_smb_end_of_file,
16125                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
16126                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
16127
16128         { &hf_smb_device_type,
16129                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
16130                 VALS(device_type_vals), 0, "Type of device", HFILL }},
16131
16132         { &hf_smb_is_directory,
16133                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
16134                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
16135
16136         { &hf_smb_next_entry_offset,
16137                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
16138                 NULL, 0, "Offset to next entry", HFILL }},
16139
16140         { &hf_smb_change_time,
16141                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
16142                 NULL, 0, "Last Change Time", HFILL }},
16143
16144         { &hf_smb_setup_len,
16145                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
16146                 NULL, 0, "Length of prionter setup data", HFILL }},
16147
16148         { &hf_smb_print_mode,
16149                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
16150                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
16151
16152         { &hf_smb_print_identifier,
16153                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
16154                 NULL, 0, "Identifier string for this print job", HFILL }},
16155
16156         { &hf_smb_restart_index,
16157                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
16158                 NULL, 0, "Index of entry after last returned", HFILL }},
16159
16160         { &hf_smb_print_queue_date,
16161                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
16162                 NULL, 0, "Date when this entry was queued", HFILL }},
16163
16164         { &hf_smb_print_queue_dos_date,
16165                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
16166                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
16167
16168         { &hf_smb_print_queue_dos_time,
16169                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
16170                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
16171
16172         { &hf_smb_print_status,
16173                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
16174                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
16175
16176         { &hf_smb_print_spool_file_number,
16177                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
16178                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
16179
16180         { &hf_smb_print_spool_file_size,
16181                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
16182                 NULL, 0, "Number of bytes in spool file", HFILL }},
16183
16184         { &hf_smb_print_spool_file_name,
16185                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
16186                 NULL, 0, "Name of client that submitted this job", HFILL }},
16187
16188         { &hf_smb_start_index,
16189                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
16190                 NULL, 0, "First queue entry to return", HFILL }},
16191
16192         { &hf_smb_cancel_to,
16193                 { "Cancel to", "smb.cancel_to", FT_UINT32, BASE_DEC,
16194                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
16195
16196         { &hf_smb_trans2_subcmd,
16197                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
16198                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
16199
16200         { &hf_smb_trans_name,
16201                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
16202                 NULL, 0, "Name of transaction", HFILL }},
16203
16204         { &hf_smb_transaction_flags_dtid,
16205                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
16206                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
16207
16208         { &hf_smb_transaction_flags_owt,
16209                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
16210                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
16211
16212         { &hf_smb_search_count,
16213                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
16214                 NULL, 0, "Maximum number of search entries to return", HFILL }},
16215
16216         { &hf_smb_search_pattern,
16217                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
16218                 NULL, 0, "Search Pattern", HFILL }},
16219
16220         { &hf_smb_ff2_backup,
16221                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
16222                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
16223
16224         { &hf_smb_ff2_continue,
16225                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
16226                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
16227
16228         { &hf_smb_ff2_resume,
16229                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
16230                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
16231
16232         { &hf_smb_ff2_close_eos,
16233                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
16234                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
16235
16236         { &hf_smb_ff2_close,
16237                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
16238                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
16239
16240         { &hf_smb_ff2_information_level,
16241                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
16242                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
16243
16244         { &hf_smb_qpi_loi,
16245                 { "Level of Interest", "smb.loi", FT_UINT16, BASE_DEC,
16246                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] commands", HFILL }},
16247
16248         { &hf_smb_storage_type,
16249                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
16250                 NULL, 0, "Type of storage", HFILL }},
16251
16252         { &hf_smb_resume,
16253                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
16254                 NULL, 0, "Resume Key", HFILL }},
16255
16256         { &hf_smb_max_referral_level,
16257                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
16258                 NULL, 0, "Latest referral version number understood", HFILL }},
16259
16260         { &hf_smb_qfsi_information_level,
16261                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_DEC,
16262                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
16263
16264         { &hf_smb_nt_rename_level,
16265                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
16266                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
16267
16268         { &hf_smb_cluster_count,
16269                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
16270                 NULL, 0, "Number of clusters", HFILL }},
16271
16272         { &hf_smb_ea_size,
16273                 { "EA Size", "smb.ea_size", FT_UINT32, BASE_DEC,
16274                 NULL, 0, "Size of file's EA information", HFILL }},
16275
16276         { &hf_smb_list_length,
16277                 { "ListLength", "smb.list_len", FT_UINT32, BASE_DEC,
16278                 NULL, 0, "Length of the remaining data", HFILL }},
16279
16280         { &hf_smb_number_of_links,
16281                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
16282                 NULL, 0, "Number of hard links to the file", HFILL }},
16283
16284         { &hf_smb_delete_pending,
16285                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
16286                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
16287
16288         { &hf_smb_index_number,
16289                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
16290                 NULL, 0, "File system unique identifier", HFILL }},
16291
16292         { &hf_smb_current_offset,
16293                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
16294                 NULL, 0, "Current offset in the file", HFILL }},
16295
16296         { &hf_smb_t2_alignment,
16297                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
16298                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
16299
16300         { &hf_smb_t2_stream_name_length,
16301                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
16302                 NULL, 0, "Length of stream name", HFILL }},
16303
16304         { &hf_smb_t2_stream_size,
16305                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
16306                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
16307
16308         { &hf_smb_t2_stream_name,
16309                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
16310                 NULL, 0, "Name of the stream", HFILL }},
16311
16312         { &hf_smb_t2_compressed_file_size,
16313                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
16314                 NULL, 0, "Size of the compressed file", HFILL }},
16315
16316         { &hf_smb_t2_compressed_format,
16317                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
16318                 NULL, 0, "Compression algorithm used", HFILL }},
16319
16320         { &hf_smb_t2_compressed_unit_shift,
16321                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
16322                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
16323
16324         { &hf_smb_t2_compressed_chunk_shift,
16325                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
16326                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
16327
16328         { &hf_smb_t2_compressed_cluster_shift,
16329                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
16330                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
16331
16332         { &hf_smb_dfs_path_consumed,
16333                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
16334                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
16335
16336         { &hf_smb_dfs_num_referrals,
16337                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
16338                 NULL, 0, "Number of referrals in this pdu", HFILL }},
16339
16340         { &hf_smb_get_dfs_server_hold_storage,
16341                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
16342                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
16343
16344         { &hf_smb_get_dfs_fielding,
16345                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
16346                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
16347
16348         { &hf_smb_dfs_referral_version,
16349                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
16350                 NULL, 0, "Version of referral element", HFILL }},
16351
16352         { &hf_smb_dfs_referral_size,
16353                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
16354                 NULL, 0, "Size of referral element", HFILL }},
16355
16356         { &hf_smb_dfs_referral_server_type,
16357                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
16358                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
16359
16360         { &hf_smb_dfs_referral_flags_strip,
16361                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
16362                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
16363
16364         { &hf_smb_dfs_referral_node_offset,
16365                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
16366                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
16367
16368         { &hf_smb_dfs_referral_node,
16369                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
16370                 NULL, 0, "Name of entity to visit next", HFILL }},
16371
16372         { &hf_smb_dfs_referral_proximity,
16373                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
16374                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
16375
16376         { &hf_smb_dfs_referral_ttl,
16377                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
16378                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
16379
16380         { &hf_smb_dfs_referral_path_offset,
16381                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
16382                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
16383
16384         { &hf_smb_dfs_referral_path,
16385                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
16386                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
16387
16388         { &hf_smb_dfs_referral_alt_path_offset,
16389                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
16390                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
16391
16392         { &hf_smb_dfs_referral_alt_path,
16393                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
16394                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
16395
16396         { &hf_smb_end_of_search,
16397                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
16398                 NULL, 0, "Was last entry returned?", HFILL }},
16399
16400         { &hf_smb_last_name_offset,
16401                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
16402                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
16403
16404         { &hf_smb_file_index,
16405                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
16406                 NULL, 0, "File index", HFILL }},
16407
16408         { &hf_smb_short_file_name,
16409                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
16410                 NULL, 0, "Short (8.3) File Name", HFILL }},
16411
16412         { &hf_smb_short_file_name_len,
16413                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
16414                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
16415
16416         { &hf_smb_fs_id,
16417                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
16418                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
16419
16420         { &hf_smb_sector_unit,
16421                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
16422                 NULL, 0, "Sectors per allocation unit", HFILL }},
16423
16424         { &hf_smb_fs_units,
16425                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
16426                 NULL, 0, "Total number of units on this filesystem", HFILL }},
16427
16428         { &hf_smb_fs_sector,
16429                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
16430                 NULL, 0, "Bytes per sector", HFILL }},
16431
16432         { &hf_smb_avail_units,
16433                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
16434                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
16435
16436         { &hf_smb_volume_serial_num,
16437                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
16438                 NULL, 0, "Volume serial number", HFILL }},
16439
16440         { &hf_smb_volume_label_len,
16441                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
16442                 NULL, 0, "Length of volume label", HFILL }},
16443
16444         { &hf_smb_volume_label,
16445                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
16446                 NULL, 0, "Volume label", HFILL }},
16447
16448         { &hf_smb_free_alloc_units64,
16449                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
16450                 NULL, 0, "Number of free allocation units", HFILL }},
16451
16452         { &hf_smb_soft_quota_limit,
16453                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
16454                 NULL, 0, "Soft Quota treshold", HFILL }},
16455
16456         { &hf_smb_hard_quota_limit,
16457                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
16458                 NULL, 0, "Hard Quota limit", HFILL }},
16459
16460         { &hf_smb_user_quota_used,
16461                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
16462                 NULL, 0, "How much Quota is used by this user", HFILL }},
16463
16464         { &hf_smb_max_name_len,
16465                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
16466                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
16467
16468         { &hf_smb_fs_name_len,
16469                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
16470                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
16471
16472         { &hf_smb_fs_name,
16473                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
16474                 NULL, 0, "Name of filesystem", HFILL }},
16475
16476         { &hf_smb_device_char_removable,
16477                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
16478                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
16479
16480         { &hf_smb_device_char_read_only,
16481                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
16482                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
16483
16484         { &hf_smb_device_char_floppy,
16485                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
16486                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
16487
16488         { &hf_smb_device_char_write_once,
16489                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
16490                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
16491
16492         { &hf_smb_device_char_remote,
16493                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
16494                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
16495
16496         { &hf_smb_device_char_mounted,
16497                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
16498                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
16499
16500         { &hf_smb_device_char_virtual,
16501                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
16502                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
16503
16504         { &hf_smb_fs_attr_css,
16505                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
16506                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
16507
16508         { &hf_smb_fs_attr_cpn,
16509                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
16510                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
16511
16512         { &hf_smb_fs_attr_pacls,
16513                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
16514                 TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
16515
16516         { &hf_smb_fs_attr_fc,
16517                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
16518                 TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
16519
16520         { &hf_smb_fs_attr_vq,
16521                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
16522                 TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
16523
16524         { &hf_smb_fs_attr_dim,
16525                 { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
16526                 TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
16527
16528         { &hf_smb_fs_attr_vic,
16529                 { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
16530                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
16531
16532         { &hf_smb_sec_desc_revision,
16533                 { "Revision", "smb.sec_desc.revision", FT_UINT16, BASE_DEC,
16534                 NULL, 0, "Version of NT Security Descriptor structure", HFILL }},
16535
16536         { &hf_smb_sid_revision,
16537                 { "Revision", "smb.sid.revision", FT_UINT8, BASE_DEC,
16538                 NULL, 0, "Version of SID structure", HFILL }},
16539
16540         { &hf_smb_sid_num_auth,
16541                 { "Num Auth", "smb.sid.num_auth", FT_UINT8, BASE_DEC,
16542                 NULL, 0, "Number of authorities for this SID", HFILL }},
16543
16544         { &hf_smb_acl_revision,
16545                 { "Revision", "smb.acl.revision", FT_UINT16, BASE_DEC,
16546                 NULL, 0, "Version of NT ACL structure", HFILL }},
16547
16548         { &hf_smb_acl_size,
16549                 { "Size", "smb.acl.size", FT_UINT16, BASE_DEC,
16550                 NULL, 0, "Size of NT ACL structure", HFILL }},
16551
16552         { &hf_smb_acl_num_aces,
16553                 { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
16554                 NULL, 0, "Number of ACE structures for this ACL", HFILL }},
16555
16556         { &hf_smb_user_quota_offset,
16557                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
16558                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
16559
16560         { &hf_smb_ace_type,
16561                 { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
16562                 VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
16563
16564         { &hf_smb_ace_size,
16565                 { "Size", "smb.ace.size", FT_UINT16, BASE_DEC,
16566                 NULL, 0, "Size of this ACE", HFILL }},
16567
16568         { &hf_smb_ace_flags_object_inherit,
16569                 { "Object Inherit", "smb.ace.flags.object_inherit", FT_BOOLEAN, 8,
16570                 TFS(&tfs_ace_flags_object_inherit), 0x01, "Will subordinate files inherit this ACE?", HFILL }},
16571
16572         { &hf_smb_ace_flags_container_inherit,
16573                 { "Container Inherit", "smb.ace.flags.container_inherit", FT_BOOLEAN, 8,
16574                 TFS(&tfs_ace_flags_container_inherit), 0x02, "Will subordinate containers inherit this ACE?", HFILL }},
16575
16576         { &hf_smb_ace_flags_non_propagate_inherit,
16577                 { "Non-Propagate Inherit", "smb.ace.flags.non_propagate_inherit", FT_BOOLEAN, 8,
16578                 TFS(&tfs_ace_flags_non_propagate_inherit), 0x04, "Will subordinate object propagate this ACE further?", HFILL }},
16579
16580         { &hf_smb_ace_flags_inherit_only,
16581                 { "Inherit Only", "smb.ace.flags.inherit_only", FT_BOOLEAN, 8,
16582                 TFS(&tfs_ace_flags_inherit_only), 0x08, "Does this ACE apply to the current object?", HFILL }},
16583
16584         { &hf_smb_ace_flags_inherited_ace,
16585                 { "Inherited ACE", "smb.ace.flags.inherited_ace", FT_BOOLEAN, 8,
16586                 TFS(&tfs_ace_flags_inherited_ace), 0x10, "Was this ACE inherited from its parent object?", HFILL }},
16587
16588         { &hf_smb_ace_flags_successful_access,
16589                 { "Audit Successful Accesses", "smb.ace.flags.successful_access", FT_BOOLEAN, 8,
16590                 TFS(&tfs_ace_flags_successful_access), 0x40, "Should successful accesses be audited?", HFILL }},
16591
16592         { &hf_smb_ace_flags_failed_access,
16593                 { "Audit Failed Accesses", "smb.ace.flags.failed_access", FT_BOOLEAN, 8,
16594                 TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
16595
16596         { &hf_smb_sec_desc_type_owner_defaulted,
16597                 { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
16598                 TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
16599
16600         { &hf_smb_sec_desc_type_group_defaulted,
16601                 { "Group Defaulted", "smb.sec_desc.type.group_defaulted", FT_BOOLEAN, 16,
16602                 TFS(&tfs_sec_desc_type_group_defaulted), 0x0002, "Is Group Defaulted?", HFILL }},
16603
16604         { &hf_smb_sec_desc_type_dacl_present,
16605                 { "DACL Present", "smb.sec_desc.type.dacl_present", FT_BOOLEAN, 16,
16606                 TFS(&tfs_sec_desc_type_dacl_present), 0x0004, "Does this SecDesc have DACL present?", HFILL }},
16607
16608         { &hf_smb_sec_desc_type_dacl_defaulted,
16609                 { "DACL Defaulted", "smb.sec_desc.type.dacl_defaulted", FT_BOOLEAN, 16,
16610                 TFS(&tfs_sec_desc_type_dacl_defaulted), 0x0008, "Does this SecDesc have DACL Defaulted?", HFILL }},
16611
16612         { &hf_smb_sec_desc_type_sacl_present,
16613                 { "SACL Present", "smb.sec_desc.type.sacl_present", FT_BOOLEAN, 16,
16614                 TFS(&tfs_sec_desc_type_sacl_present), 0x0010, "Is the SACL present?", HFILL }},
16615
16616         { &hf_smb_sec_desc_type_sacl_defaulted,
16617                 { "SACL Defaulted", "smb.sec_desc.type.sacl_defaulted", FT_BOOLEAN, 16,
16618                 TFS(&tfs_sec_desc_type_sacl_defaulted), 0x0020, "Does this SecDesc have SACL Defaulted?", HFILL }},
16619
16620         { &hf_smb_sec_desc_type_dacl_auto_inherit_req,
16621                 { "DACL Auto Inherit Required", "smb.sec_desc.type.dacl_auto_inherit_req", FT_BOOLEAN, 16,
16622                 TFS(&tfs_sec_desc_type_dacl_auto_inherit_req), 0x0100, "Does this SecDesc have DACL Auto Inherit Required set?", HFILL }},
16623
16624         { &hf_smb_sec_desc_type_sacl_auto_inherit_req,
16625                 { "SACL Auto Inherit Required", "smb.sec_desc.type.sacl_auto_inherit_req", FT_BOOLEAN, 16,
16626                 TFS(&tfs_sec_desc_type_sacl_auto_inherit_req), 0x0200, "Does this SecDesc have SACL Auto Inherit Required set?", HFILL }},
16627
16628         { &hf_smb_sec_desc_type_dacl_auto_inherited,
16629                 { "DACL Auto Inherited", "smb.sec_desc.type.dacl_auto_inherited", FT_BOOLEAN, 16,
16630                 TFS(&tfs_sec_desc_type_dacl_auto_inherited), 0x0400, "Is this DACL auto inherited", HFILL }},
16631
16632         { &hf_smb_sec_desc_type_sacl_auto_inherited,
16633                 { "SACL Auto Inherited", "smb.sec_desc.type.sacl_auto_inherited", FT_BOOLEAN, 16,
16634                 TFS(&tfs_sec_desc_type_sacl_auto_inherited), 0x0800, "Is this SACL auto inherited", HFILL }},
16635
16636         { &hf_smb_sec_desc_type_dacl_protected,
16637                 { "DACL Protected", "smb.sec_desc.type.dacl_protected", FT_BOOLEAN, 16,
16638                 TFS(&tfs_sec_desc_type_dacl_protected), 0x1000, "Is the DACL structure protected?", HFILL }},
16639
16640         { &hf_smb_sec_desc_type_sacl_protected,
16641                 { "SACL Protected", "smb.sec_desc.type.sacl_protected", FT_BOOLEAN, 16,
16642                 TFS(&tfs_sec_desc_type_sacl_protected), 0x2000, "Is the SACL structure protected?", HFILL }},
16643
16644         { &hf_smb_sec_desc_type_self_relative,
16645                 { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
16646                 TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
16647
16648         { &hf_smb_quota_flags_deny_disk,
16649                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
16650                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
16651
16652         { &hf_smb_quota_flags_log_limit,
16653                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
16654                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
16655
16656         { &hf_smb_quota_flags_log_warning,
16657                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
16658                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
16659
16660         { &hf_smb_quota_flags_enabled,
16661                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
16662                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
16663
16664         };
16665         static gint *ett[] = {
16666                 &ett_smb,
16667                 &ett_smb_hdr,
16668                 &ett_smb_command,
16669                 &ett_smb_fileattributes,
16670                 &ett_smb_capabilities,
16671                 &ett_smb_aflags,
16672                 &ett_smb_dialect,
16673                 &ett_smb_dialects,
16674                 &ett_smb_mode,
16675                 &ett_smb_rawmode,
16676                 &ett_smb_flags,
16677                 &ett_smb_flags2,
16678                 &ett_smb_desiredaccess,
16679                 &ett_smb_search,
16680                 &ett_smb_file,
16681                 &ett_smb_openfunction,
16682                 &ett_smb_filetype,
16683                 &ett_smb_openaction,
16684                 &ett_smb_writemode,
16685                 &ett_smb_lock_type,
16686                 &ett_smb_ssetupandxaction,
16687                 &ett_smb_optionsup,
16688                 &ett_smb_time_date,
16689                 &ett_smb_move_flags,
16690                 &ett_smb_file_attributes,
16691                 &ett_smb_search_resume_key,
16692                 &ett_smb_search_dir_info,
16693                 &ett_smb_unlocks,
16694                 &ett_smb_unlock,
16695                 &ett_smb_locks,
16696                 &ett_smb_lock,
16697                 &ett_smb_open_flags,
16698                 &ett_smb_ipc_state,
16699                 &ett_smb_open_action,
16700                 &ett_smb_setup_action,
16701                 &ett_smb_connect_flags,
16702                 &ett_smb_connect_support_bits,
16703                 &ett_smb_nt_access_mask,
16704                 &ett_smb_nt_create_bits,
16705                 &ett_smb_nt_create_options,
16706                 &ett_smb_nt_share_access,
16707                 &ett_smb_nt_security_flags,
16708                 &ett_smb_nt_trans_setup,
16709                 &ett_smb_nt_trans_data,
16710                 &ett_smb_nt_trans_param,
16711                 &ett_smb_nt_notify_completion_filter,
16712                 &ett_smb_nt_ioctl_flags,
16713                 &ett_smb_security_information_mask,
16714                 &ett_smb_print_queue_entry,
16715                 &ett_smb_transaction_flags,
16716                 &ett_smb_transaction_params,
16717                 &ett_smb_find_first2_flags,
16718                 &ett_smb_transaction_data,
16719                 &ett_smb_stream_info,
16720                 &ett_smb_dfs_referrals,
16721                 &ett_smb_dfs_referral,
16722                 &ett_smb_dfs_referral_flags,
16723                 &ett_smb_get_dfs_flags,
16724                 &ett_smb_ff2_data,
16725                 &ett_smb_device_characteristics,
16726                 &ett_smb_fs_attributes,
16727                 &ett_smb_segments,
16728                 &ett_smb_sec_desc,
16729                 &ett_smb_sid,
16730                 &ett_smb_acl,
16731                 &ett_smb_ace,
16732                 &ett_smb_ace_flags,
16733                 &ett_smb_sec_desc_type,
16734                 &ett_smb_quotaflags,
16735         };
16736         module_t *smb_module;
16737
16738         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
16739             "SMB", "smb");
16740         proto_register_subtree_array(ett, array_length(ett));
16741         proto_register_field_array(proto_smb, hf, array_length(hf));
16742         register_init_routine(&smb_init_protocol);
16743         smb_module = prefs_register_protocol(proto_smb, NULL);
16744         prefs_register_bool_preference(smb_module, "trans_reassembly",
16745                 "Reassemble SMB Transaction payload",
16746                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
16747                 &smb_trans_reassembly);
16748         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
16749                 "Reassemble DCERPC over SMB",
16750                 "Whether the dissector should reassemble DCERPC over SMB commands",
16751                 &smb_dcerpc_reassembly);
16752         register_init_routine(smb_trans_reassembly_init);
16753         register_init_routine(smb_dcerpc_reassembly_init);
16754 }
16755
16756 void
16757 proto_reg_handoff_smb(void)
16758 {
16759         heur_dissector_add("netbios", dissect_smb, proto_smb);
16760 }